GK SDK 源码库: XMIPCLinuxV100R005C00SPC030 (kernel/tools/open_source excluded)
This commit is contained in:
@@ -0,0 +1,69 @@
|
||||
config RAM
|
||||
bool "Enable RAM drivers using Driver Model"
|
||||
depends on DM
|
||||
help
|
||||
This allows drivers to be provided for SDRAM and other RAM
|
||||
controllers and their type to be specified in the board's device
|
||||
tree. Generally some parameters are required to set up the RAM and
|
||||
the RAM size can either be statically defined or dynamically
|
||||
detected.
|
||||
|
||||
config SPL_RAM
|
||||
bool "Enable RAM support in SPL"
|
||||
depends on RAM && SPL_DM
|
||||
help
|
||||
The RAM subsystem adds a small amount of overhead to the image.
|
||||
If this is acceptable and you have a need to use RAM drivers in
|
||||
SPL, enable this option. It might provide a cleaner interface to
|
||||
setting up RAM (e.g. SDRAM / DDR) within SPL.
|
||||
|
||||
config TPL_RAM
|
||||
bool "Enable RAM support in TPL"
|
||||
depends on RAM
|
||||
help
|
||||
The RAM subsystem adds a small amount of overhead to the image.
|
||||
If this is acceptable and you have a need to use RAM drivers in
|
||||
TPL, enable this option. It might provide a cleaner interface to
|
||||
setting up RAM (e.g. SDRAM / DDR) within TPL.
|
||||
|
||||
config STM32_SDRAM
|
||||
bool "Enable STM32 SDRAM support"
|
||||
depends on RAM
|
||||
help
|
||||
STM32F7 family devices support flexible memory controller(FMC) to
|
||||
support external memories like sdram, psram & nand.
|
||||
This driver is for the sdram memory interface with the FMC.
|
||||
|
||||
config MPC83XX_SDRAM
|
||||
bool "Enable MPC83XX SDRAM support"
|
||||
depends on RAM
|
||||
help
|
||||
Enable support for the internal DDR Memory Controller of the MPC83xx
|
||||
family of SoCs. Both static configurations, as well as configuring
|
||||
the RAM through the use of SPD (Serial Presence Detect) is supported
|
||||
via device tree settings.
|
||||
|
||||
config K3_AM654_DDRSS
|
||||
bool "Enable AM654 DDRSS support"
|
||||
depends on RAM && SOC_K3_AM6
|
||||
help
|
||||
K3 based AM654 devices has DDR memory subsystem that comprises
|
||||
Synopys DDR controller, Synopsis DDR phy and wrapper logic to
|
||||
intergrate these blocks into the device. This DDR subsystem
|
||||
provides an interface to external SDRAM devices. Enabling this
|
||||
config add support for the initialization of the external
|
||||
SDRAM devices connected to DDR subsystem.
|
||||
|
||||
config K3_J721E_DDRSS
|
||||
bool "Enable J721E DDRSS support"
|
||||
depends on RAM
|
||||
help
|
||||
The J721E DDR subsystem comprises DDR controller, DDR PHY and
|
||||
wrapper logic to integrate these blocks in the device. The DDR
|
||||
subsystem is used to provide an interface to external SDRAM
|
||||
devices which can be utilized for storing program or data.
|
||||
Enabling this config adds support for the DDR memory controller
|
||||
on J721E family of SoCs.
|
||||
|
||||
source "drivers/ram/rockchip/Kconfig"
|
||||
source "drivers/ram/stm32mp1/Kconfig"
|
||||
@@ -0,0 +1,17 @@
|
||||
# SPDX-License-Identifier: GPL-2.0+
|
||||
#
|
||||
# Copyright (c) 2015 Google, Inc
|
||||
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
#
|
||||
obj-$(CONFIG_RAM) += ram-uclass.o
|
||||
obj-$(CONFIG_MPC83XX_SDRAM) += mpc83xx_sdram.o
|
||||
obj-$(CONFIG_SANDBOX) += sandbox_ram.o
|
||||
obj-$(CONFIG_STM32MP1_DDR) += stm32mp1/
|
||||
obj-$(CONFIG_STM32_SDRAM) += stm32_sdram.o
|
||||
obj-$(CONFIG_ARCH_BMIPS) += bmips_ram.o
|
||||
|
||||
obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip/
|
||||
|
||||
obj-$(CONFIG_K3_AM654_DDRSS) += k3-am654-ddrss.o
|
||||
obj-$(CONFIG_ARCH_MEDIATEK) += mediatek/
|
||||
obj-$(CONFIG_K3_J721E_DDRSS) += k3-j721e/
|
||||
@@ -0,0 +1,176 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright (C) 2017 Álvaro Fernández Rojas <noltari@gmail.com>
|
||||
*
|
||||
* Derived from linux/arch/mips/bcm63xx/cpu.c:
|
||||
* Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr>
|
||||
* Copyright (C) 2009 Florian Fainelli <florian@openwrt.org>
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <errno.h>
|
||||
#include <ram.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
#define SDRAM_CFG_REG 0x0
|
||||
#define SDRAM_CFG_COL_SHIFT 4
|
||||
#define SDRAM_CFG_COL_MASK (0x3 << SDRAM_CFG_COL_SHIFT)
|
||||
#define SDRAM_CFG_ROW_SHIFT 6
|
||||
#define SDRAM_CFG_ROW_MASK (0x3 << SDRAM_CFG_ROW_SHIFT)
|
||||
#define SDRAM_CFG_32B_SHIFT 10
|
||||
#define SDRAM_CFG_32B_MASK (1 << SDRAM_CFG_32B_SHIFT)
|
||||
#define SDRAM_CFG_BANK_SHIFT 13
|
||||
#define SDRAM_CFG_BANK_MASK (1 << SDRAM_CFG_BANK_SHIFT)
|
||||
#define SDRAM_6318_SPACE_SHIFT 4
|
||||
#define SDRAM_6318_SPACE_MASK (0xf << SDRAM_6318_SPACE_SHIFT)
|
||||
|
||||
#define MEMC_CFG_REG 0x4
|
||||
#define MEMC_CFG_32B_SHIFT 1
|
||||
#define MEMC_CFG_32B_MASK (1 << MEMC_CFG_32B_SHIFT)
|
||||
#define MEMC_CFG_COL_SHIFT 3
|
||||
#define MEMC_CFG_COL_MASK (0x3 << MEMC_CFG_COL_SHIFT)
|
||||
#define MEMC_CFG_ROW_SHIFT 6
|
||||
#define MEMC_CFG_ROW_MASK (0x3 << MEMC_CFG_ROW_SHIFT)
|
||||
|
||||
#define DDR_CSEND_REG 0x8
|
||||
|
||||
struct bmips_ram_priv;
|
||||
|
||||
struct bmips_ram_hw {
|
||||
ulong (*get_ram_size)(struct bmips_ram_priv *);
|
||||
};
|
||||
|
||||
struct bmips_ram_priv {
|
||||
void __iomem *regs;
|
||||
u32 force_size;
|
||||
const struct bmips_ram_hw *hw;
|
||||
};
|
||||
|
||||
static ulong bcm6318_get_ram_size(struct bmips_ram_priv *priv)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
val = readl_be(priv->regs + SDRAM_CFG_REG);
|
||||
val = (val & SDRAM_6318_SPACE_MASK) >> SDRAM_6318_SPACE_SHIFT;
|
||||
|
||||
return (1 << (val + 20));
|
||||
}
|
||||
|
||||
static ulong bcm6328_get_ram_size(struct bmips_ram_priv *priv)
|
||||
{
|
||||
return readl_be(priv->regs + DDR_CSEND_REG) << 24;
|
||||
}
|
||||
|
||||
static ulong bmips_dram_size(unsigned int cols, unsigned int rows,
|
||||
unsigned int is_32b, unsigned int banks)
|
||||
{
|
||||
rows += 11; /* 0 => 11 address bits ... 2 => 13 address bits */
|
||||
cols += 8; /* 0 => 8 address bits ... 2 => 10 address bits */
|
||||
is_32b += 1;
|
||||
|
||||
return 1 << (cols + rows + is_32b + banks);
|
||||
}
|
||||
|
||||
static ulong bcm6338_get_ram_size(struct bmips_ram_priv *priv)
|
||||
{
|
||||
unsigned int cols = 0, rows = 0, is_32b = 0, banks = 0;
|
||||
u32 val;
|
||||
|
||||
val = readl_be(priv->regs + SDRAM_CFG_REG);
|
||||
rows = (val & SDRAM_CFG_ROW_MASK) >> SDRAM_CFG_ROW_SHIFT;
|
||||
cols = (val & SDRAM_CFG_COL_MASK) >> SDRAM_CFG_COL_SHIFT;
|
||||
is_32b = (val & SDRAM_CFG_32B_MASK) ? 1 : 0;
|
||||
banks = (val & SDRAM_CFG_BANK_MASK) ? 2 : 1;
|
||||
|
||||
return bmips_dram_size(cols, rows, is_32b, banks);
|
||||
}
|
||||
|
||||
static ulong bcm6358_get_ram_size(struct bmips_ram_priv *priv)
|
||||
{
|
||||
unsigned int cols = 0, rows = 0, is_32b = 0;
|
||||
u32 val;
|
||||
|
||||
val = readl_be(priv->regs + MEMC_CFG_REG);
|
||||
rows = (val & MEMC_CFG_ROW_MASK) >> MEMC_CFG_ROW_SHIFT;
|
||||
cols = (val & MEMC_CFG_COL_MASK) >> MEMC_CFG_COL_SHIFT;
|
||||
is_32b = (val & MEMC_CFG_32B_MASK) ? 0 : 1;
|
||||
|
||||
return bmips_dram_size(cols, rows, is_32b, 2);
|
||||
}
|
||||
|
||||
static int bmips_ram_get_info(struct udevice *dev, struct ram_info *info)
|
||||
{
|
||||
struct bmips_ram_priv *priv = dev_get_priv(dev);
|
||||
const struct bmips_ram_hw *hw = priv->hw;
|
||||
|
||||
info->base = 0x80000000;
|
||||
if (priv->force_size)
|
||||
info->size = priv->force_size;
|
||||
else
|
||||
info->size = hw->get_ram_size(priv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct ram_ops bmips_ram_ops = {
|
||||
.get_info = bmips_ram_get_info,
|
||||
};
|
||||
|
||||
static const struct bmips_ram_hw bmips_ram_bcm6318 = {
|
||||
.get_ram_size = bcm6318_get_ram_size,
|
||||
};
|
||||
|
||||
static const struct bmips_ram_hw bmips_ram_bcm6328 = {
|
||||
.get_ram_size = bcm6328_get_ram_size,
|
||||
};
|
||||
|
||||
static const struct bmips_ram_hw bmips_ram_bcm6338 = {
|
||||
.get_ram_size = bcm6338_get_ram_size,
|
||||
};
|
||||
|
||||
static const struct bmips_ram_hw bmips_ram_bcm6358 = {
|
||||
.get_ram_size = bcm6358_get_ram_size,
|
||||
};
|
||||
|
||||
static const struct udevice_id bmips_ram_ids[] = {
|
||||
{
|
||||
.compatible = "brcm,bcm6318-mc",
|
||||
.data = (ulong)&bmips_ram_bcm6318,
|
||||
}, {
|
||||
.compatible = "brcm,bcm6328-mc",
|
||||
.data = (ulong)&bmips_ram_bcm6328,
|
||||
}, {
|
||||
.compatible = "brcm,bcm6338-mc",
|
||||
.data = (ulong)&bmips_ram_bcm6338,
|
||||
}, {
|
||||
.compatible = "brcm,bcm6358-mc",
|
||||
.data = (ulong)&bmips_ram_bcm6358,
|
||||
}, { /* sentinel */ }
|
||||
};
|
||||
|
||||
static int bmips_ram_probe(struct udevice *dev)
|
||||
{
|
||||
struct bmips_ram_priv *priv = dev_get_priv(dev);
|
||||
const struct bmips_ram_hw *hw =
|
||||
(const struct bmips_ram_hw *)dev_get_driver_data(dev);
|
||||
|
||||
priv->regs = dev_remap_addr(dev);
|
||||
if (!priv->regs)
|
||||
return -EINVAL;
|
||||
|
||||
dev_read_u32(dev, "force-size", &priv->force_size);
|
||||
|
||||
priv->hw = hw;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
U_BOOT_DRIVER(bmips_ram) = {
|
||||
.name = "bmips-mc",
|
||||
.id = UCLASS_RAM,
|
||||
.of_match = bmips_ram_ids,
|
||||
.probe = bmips_ram_probe,
|
||||
.priv_auto_alloc_size = sizeof(struct bmips_ram_priv),
|
||||
.ops = &bmips_ram_ops,
|
||||
};
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,8 @@
|
||||
# SPDX-License-Identifier: GPL-2.0+
|
||||
#
|
||||
# Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com/
|
||||
#
|
||||
|
||||
obj-$(CONFIG_K3_J721E_DDRSS) += k3-j721e-ddrss.o
|
||||
obj-$(CONFIG_K3_J721E_DDRSS) += lpddr4_obj_if.o
|
||||
obj-$(CONFIG_K3_J721E_DDRSS) += lpddr4.o
|
||||
@@ -0,0 +1,119 @@
|
||||
/* SPDX-License-Identifier: BSD-3-Clause */
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2017-2018 Cadence Design Systems, Inc.
|
||||
* Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com/
|
||||
*
|
||||
* cps_drv_lpddr4.h
|
||||
* Interface for the Register Accaess Layer of Cadence Platform Service (CPS)
|
||||
*****************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef CPS_DRV_H_
|
||||
#define CPS_DRV_H_
|
||||
|
||||
#include <stddef.h>
|
||||
#include <inttypes.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
/**
|
||||
* \brief Read a 32-bit value from memory.
|
||||
* \param reg address of the memory mapped hardware register
|
||||
* \return the value at the given address
|
||||
*/
|
||||
#define CPS_REG_READ(reg) (readl((volatile uint32_t*)(reg)))
|
||||
|
||||
/**
|
||||
* \brief Write a 32-bit address value to memory.
|
||||
* \param reg address of the memory mapped hardware register
|
||||
* \param value unsigned 32-bit value to write
|
||||
*/
|
||||
#define CPS_REG_WRITE(reg, value) (writel((uint32_t)(value), (volatile uint32_t*)(reg)))
|
||||
|
||||
/**
|
||||
* \brief Subtitue the value of fld macro and concatinate with required string
|
||||
* \param fld field name
|
||||
*/
|
||||
#define CPS_FLD_MASK(fld) (fld ## _MASK)
|
||||
#define CPS_FLD_SHIFT(fld) (fld ## _SHIFT)
|
||||
#define CPS_FLD_WIDTH(fld) (fld ## _WIDTH)
|
||||
#define CPS_FLD_WOCLR(fld) (fld ## _WOCLR)
|
||||
#define CPS_FLD_WOSET(fld) (fld ## _WOSET)
|
||||
|
||||
/**
|
||||
* \brief Read a value of bit-field from the register value.
|
||||
* \param reg register name
|
||||
* \param fld field name
|
||||
* \param reg_value register value
|
||||
* \return bit-field value
|
||||
*/
|
||||
#define CPS_FLD_READ(fld, reg_value) (cps_fldread((uint32_t)(CPS_FLD_MASK(fld)), \
|
||||
(uint32_t)(CPS_FLD_SHIFT(fld)), \
|
||||
(uint32_t)(reg_value)))
|
||||
|
||||
/**
|
||||
* \brief Write a value of the bit-field into the register value.
|
||||
* \param reg register name
|
||||
* \param fld field name
|
||||
* \param reg_value register value
|
||||
* \param value value to be written to bit-field
|
||||
* \return modified register value
|
||||
*/
|
||||
#define CPS_FLD_WRITE(fld, reg_value, value) (cps_fldwrite((uint32_t)(CPS_FLD_MASK(fld)), \
|
||||
(uint32_t)(CPS_FLD_SHIFT(fld)), \
|
||||
(uint32_t)(reg_value), (uint32_t)(value)))
|
||||
|
||||
/**
|
||||
* \brief Set bit within the register value.
|
||||
* \param reg register name
|
||||
* \param fld field name
|
||||
* \param reg_value register value
|
||||
* \return modified register value
|
||||
*/
|
||||
#define CPS_FLD_SET(fld, reg_value) (cps_fldset((uint32_t)(CPS_FLD_WIDTH(fld)), \
|
||||
(uint32_t)(CPS_FLD_MASK(fld)), \
|
||||
(uint32_t)(CPS_FLD_WOCLR(fld)), \
|
||||
(uint32_t)(reg_value)))
|
||||
|
||||
static inline uint32_t cps_fldread(uint32_t mask, uint32_t shift, uint32_t reg_value)
|
||||
{
|
||||
uint32_t result = (reg_value & mask) >> shift;
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Write a value of the bit-field into the register value.
|
||||
* \param mask mask for the bit-field
|
||||
* \param shift bit-field shift from LSB
|
||||
* \param reg_value register value
|
||||
* \param value value to be written to bit-field
|
||||
* \return modified register value
|
||||
*/
|
||||
static inline uint32_t cps_fldwrite(uint32_t mask, uint32_t shift, uint32_t reg_value, uint32_t value)
|
||||
{
|
||||
uint32_t new_value = (value << shift) & mask;
|
||||
|
||||
new_value = (reg_value & ~mask) | new_value;
|
||||
return (new_value);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set bit within the register value.
|
||||
* \param width width of the bit-field
|
||||
* \param mask mask for the bit-field
|
||||
* \param is_woclr is bit-field has 'write one to clear' flag set
|
||||
* \param reg_value register value
|
||||
* \return modified register value
|
||||
*/
|
||||
static inline uint32_t cps_fldset(uint32_t width, uint32_t mask, uint32_t is_woclr, uint32_t reg_value)
|
||||
{
|
||||
uint32_t new_value = reg_value;
|
||||
/* Confirm the field to be bit and not write to clear type */
|
||||
if ((width == 1U) && (is_woclr == 0U)) {
|
||||
new_value |= mask;
|
||||
}
|
||||
|
||||
return (new_value);
|
||||
}
|
||||
#endif /* CPS_DRV_H_ */
|
||||
@@ -0,0 +1,372 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Texas Instruments' J721E DDRSS driver
|
||||
*
|
||||
* Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com/
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <clk.h>
|
||||
#include <dm.h>
|
||||
#include <ram.h>
|
||||
#include <asm/io.h>
|
||||
#include <power-domain.h>
|
||||
#include <wait_bit.h>
|
||||
|
||||
#include "lpddr4_obj_if.h"
|
||||
#include "lpddr4_if.h"
|
||||
#include "lpddr4_structs_if.h"
|
||||
#include "lpddr4_ctl_regs.h"
|
||||
|
||||
#define SRAM_MAX 512
|
||||
|
||||
#define CTRLMMR_DDR4_FSP_CLKCHNG_REQ_OFFS 0x80
|
||||
#define CTRLMMR_DDR4_FSP_CLKCHNG_ACK_OFFS 0xc0
|
||||
|
||||
struct j721e_ddrss_desc {
|
||||
struct udevice *dev;
|
||||
void __iomem *ddrss_ss_cfg;
|
||||
void __iomem *ddrss_ctrl_mmr;
|
||||
struct power_domain ddrcfg_pwrdmn;
|
||||
struct power_domain ddrdata_pwrdmn;
|
||||
struct clk ddr_clk;
|
||||
struct clk osc_clk;
|
||||
u32 ddr_freq1;
|
||||
u32 ddr_freq2;
|
||||
u32 ddr_fhs_cnt;
|
||||
};
|
||||
|
||||
static LPDDR4_OBJ *driverdt;
|
||||
static lpddr4_config config;
|
||||
static lpddr4_privatedata pd;
|
||||
|
||||
static struct j721e_ddrss_desc *ddrss;
|
||||
|
||||
#define TH_MACRO_EXP(fld, str) (fld##str)
|
||||
|
||||
#define TH_FLD_MASK(fld) TH_MACRO_EXP(fld, _MASK)
|
||||
#define TH_FLD_SHIFT(fld) TH_MACRO_EXP(fld, _SHIFT)
|
||||
#define TH_FLD_WIDTH(fld) TH_MACRO_EXP(fld, _WIDTH)
|
||||
#define TH_FLD_WOCLR(fld) TH_MACRO_EXP(fld, _WOCLR)
|
||||
#define TH_FLD_WOSET(fld) TH_MACRO_EXP(fld, _WOSET)
|
||||
|
||||
#define str(s) #s
|
||||
#define xstr(s) str(s)
|
||||
|
||||
#define CTL_SHIFT 11
|
||||
#define PHY_SHIFT 11
|
||||
#define PI_SHIFT 10
|
||||
|
||||
#define TH_OFFSET_FROM_REG(REG, SHIFT, offset) do {\
|
||||
char *i, *pstr= xstr(REG); offset = 0;\
|
||||
for (i = &pstr[SHIFT]; *i != '\0'; ++i) {\
|
||||
offset = offset * 10 + (*i - '0'); }\
|
||||
} while (0)
|
||||
|
||||
static void j721e_lpddr4_ack_freq_upd_req(void)
|
||||
{
|
||||
unsigned int req_type, counter;
|
||||
|
||||
debug("--->>> LPDDR4 Initialization is in progress ... <<<---\n");
|
||||
|
||||
for (counter = 0; counter < ddrss->ddr_fhs_cnt; counter++) {
|
||||
if (wait_for_bit_le32(ddrss->ddrss_ctrl_mmr +
|
||||
CTRLMMR_DDR4_FSP_CLKCHNG_REQ_OFFS, 0x80,
|
||||
true, 10000, false)) {
|
||||
printf("Timeout during frequency handshake\n");
|
||||
hang();
|
||||
}
|
||||
|
||||
req_type = readl(ddrss->ddrss_ctrl_mmr +
|
||||
CTRLMMR_DDR4_FSP_CLKCHNG_REQ_OFFS) & 0x03;
|
||||
|
||||
debug("%s: received freq change req: req type = %d, req no. = %d \n",
|
||||
__func__, req_type, counter);
|
||||
|
||||
if (req_type == 1)
|
||||
clk_set_rate(&ddrss->ddr_clk, ddrss->ddr_freq1);
|
||||
else if (req_type == 2)
|
||||
clk_set_rate(&ddrss->ddr_clk, ddrss->ddr_freq2);
|
||||
else if (req_type == 0)
|
||||
/* Put DDR pll in bypass mode */
|
||||
clk_set_rate(&ddrss->ddr_clk,
|
||||
clk_get_rate(&ddrss->osc_clk));
|
||||
else
|
||||
printf("%s: Invalid freq request type\n", __func__);
|
||||
|
||||
writel(0x1, ddrss->ddrss_ctrl_mmr +
|
||||
CTRLMMR_DDR4_FSP_CLKCHNG_ACK_OFFS);
|
||||
if (wait_for_bit_le32(ddrss->ddrss_ctrl_mmr +
|
||||
CTRLMMR_DDR4_FSP_CLKCHNG_REQ_OFFS, 0x80,
|
||||
false, 10, false)) {
|
||||
printf("Timeout during frequency handshake\n");
|
||||
hang();
|
||||
}
|
||||
writel(0x0, ddrss->ddrss_ctrl_mmr +
|
||||
CTRLMMR_DDR4_FSP_CLKCHNG_ACK_OFFS);
|
||||
}
|
||||
}
|
||||
|
||||
static void j721e_lpddr4_info_handler(const lpddr4_privatedata * pd,
|
||||
lpddr4_infotype infotype)
|
||||
{
|
||||
if (infotype == LPDDR4_DRV_SOC_PLL_UPDATE) {
|
||||
j721e_lpddr4_ack_freq_upd_req();
|
||||
}
|
||||
}
|
||||
|
||||
static int j721e_ddrss_power_on(struct j721e_ddrss_desc *ddrss)
|
||||
{
|
||||
int ret;
|
||||
|
||||
debug("%s(ddrss=%p)\n", __func__, ddrss);
|
||||
|
||||
ret = power_domain_on(&ddrss->ddrcfg_pwrdmn);
|
||||
if (ret) {
|
||||
dev_err(ddrss->dev, "power_domain_on() failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = power_domain_on(&ddrss->ddrdata_pwrdmn);
|
||||
if (ret) {
|
||||
dev_err(ddrss->dev, "power_domain_on() failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int j721e_ddrss_ofdata_to_priv(struct udevice *dev)
|
||||
{
|
||||
struct j721e_ddrss_desc *ddrss = dev_get_priv(dev);
|
||||
phys_addr_t reg;
|
||||
int ret;
|
||||
|
||||
debug("%s(dev=%p)\n", __func__, dev);
|
||||
|
||||
reg = dev_read_addr_name(dev, "cfg");
|
||||
if (reg == FDT_ADDR_T_NONE) {
|
||||
dev_err(dev, "No reg property for DDRSS wrapper logic\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
ddrss->ddrss_ss_cfg = (void *)reg;
|
||||
|
||||
reg = dev_read_addr_name(dev, "ctrl_mmr_lp4");
|
||||
if (reg == FDT_ADDR_T_NONE) {
|
||||
dev_err(dev, "No reg property for CTRL MMR\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
ddrss->ddrss_ctrl_mmr = (void *)reg;
|
||||
|
||||
ret = power_domain_get_by_index(dev, &ddrss->ddrcfg_pwrdmn, 0);
|
||||
if (ret) {
|
||||
dev_err(dev, "power_domain_get() failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = power_domain_get_by_index(dev, &ddrss->ddrdata_pwrdmn, 1);
|
||||
if (ret) {
|
||||
dev_err(dev, "power_domain_get() failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = clk_get_by_index(dev, 0, &ddrss->ddr_clk);
|
||||
if (ret)
|
||||
dev_err(dev, "clk get failed%d\n", ret);
|
||||
|
||||
ret = clk_get_by_index(dev, 1, &ddrss->osc_clk);
|
||||
if (ret)
|
||||
dev_err(dev, "clk get failed for osc clk %d\n", ret);
|
||||
|
||||
ret = dev_read_u32(dev, "ti,ddr-freq1", &ddrss->ddr_freq1);
|
||||
if (ret)
|
||||
dev_err(dev, "ddr freq1 not populated %d\n", ret);
|
||||
|
||||
ret = dev_read_u32(dev, "ti,ddr-freq2", &ddrss->ddr_freq2);
|
||||
if (ret)
|
||||
dev_err(dev, "ddr freq2 not populated %d\n", ret);
|
||||
|
||||
ret = dev_read_u32(dev, "ti,ddr-fhs-cnt", &ddrss->ddr_fhs_cnt);
|
||||
if (ret)
|
||||
dev_err(dev, "ddr fhs cnt not populated %d\n", ret);
|
||||
|
||||
/* Put DDR pll in bypass mode */
|
||||
ret = clk_set_rate(&ddrss->ddr_clk, clk_get_rate(&ddrss->osc_clk));
|
||||
if (ret)
|
||||
dev_err(dev, "ddr clk bypass failed\n");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void j721e_lpddr4_probe(void)
|
||||
{
|
||||
uint32_t status = 0U;
|
||||
uint16_t configsize = 0U;
|
||||
|
||||
status = driverdt->probe(&config, &configsize);
|
||||
|
||||
if ((status != 0) || (configsize != sizeof(lpddr4_privatedata))
|
||||
|| (configsize > SRAM_MAX)) {
|
||||
printf("LPDDR4_Probe: FAIL\n");
|
||||
hang();
|
||||
} else {
|
||||
debug("LPDDR4_Probe: PASS\n");
|
||||
}
|
||||
}
|
||||
|
||||
void j721e_lpddr4_init(void)
|
||||
{
|
||||
uint32_t status = 0U;
|
||||
|
||||
if ((sizeof(pd) != sizeof(lpddr4_privatedata))
|
||||
|| (sizeof(pd) > SRAM_MAX)) {
|
||||
printf("LPDDR4_Init: FAIL\n");
|
||||
hang();
|
||||
}
|
||||
|
||||
config.ctlbase = (struct lpddr4_ctlregs_s *)ddrss->ddrss_ss_cfg;
|
||||
config.infohandler = (lpddr4_infocallback) j721e_lpddr4_info_handler;
|
||||
|
||||
status = driverdt->init(&pd, &config);
|
||||
|
||||
if ((status > 0U) ||
|
||||
(pd.ctlbase != (struct lpddr4_ctlregs_s *)config.ctlbase) ||
|
||||
(pd.ctlinterrupthandler != config.ctlinterrupthandler) ||
|
||||
(pd.phyindepinterrupthandler != config.phyindepinterrupthandler)) {
|
||||
printf("LPDDR4_Init: FAIL\n");
|
||||
hang();
|
||||
} else {
|
||||
debug("LPDDR4_Init: PASS\n");
|
||||
}
|
||||
}
|
||||
|
||||
void populate_data_array_from_dt(lpddr4_reginitdata * reginit_data)
|
||||
{
|
||||
int ret, i;
|
||||
|
||||
ret = dev_read_u32_array(ddrss->dev, "ti,ctl-data",
|
||||
(u32 *) reginit_data->denalictlreg,
|
||||
LPDDR4_CTL_REG_COUNT);
|
||||
if (ret)
|
||||
printf("Error reading ctrl data\n");
|
||||
|
||||
for (i = 0; i < LPDDR4_CTL_REG_COUNT; i++)
|
||||
reginit_data->updatectlreg[i] = true;
|
||||
|
||||
ret = dev_read_u32_array(ddrss->dev, "ti,pi-data",
|
||||
(u32 *) reginit_data->denaliphyindepreg,
|
||||
LPDDR4_PHY_INDEP_REG_COUNT);
|
||||
if (ret)
|
||||
printf("Error reading PI data\n");
|
||||
|
||||
for (i = 0; i < LPDDR4_PHY_INDEP_REG_COUNT; i++)
|
||||
reginit_data->updatephyindepreg[i] = true;
|
||||
|
||||
ret = dev_read_u32_array(ddrss->dev, "ti,phy-data",
|
||||
(u32 *) reginit_data->denaliphyreg,
|
||||
LPDDR4_PHY_REG_COUNT);
|
||||
if (ret)
|
||||
printf("Error reading PHY data\n");
|
||||
|
||||
for (i = 0; i < LPDDR4_PHY_REG_COUNT; i++)
|
||||
reginit_data->updatephyreg[i] = true;
|
||||
}
|
||||
|
||||
void j721e_lpddr4_hardware_reg_init(void)
|
||||
{
|
||||
uint32_t status = 0U;
|
||||
lpddr4_reginitdata reginitdata;
|
||||
|
||||
populate_data_array_from_dt(®initdata);
|
||||
|
||||
status = driverdt->writectlconfig(&pd, ®initdata);
|
||||
if (!status) {
|
||||
status = driverdt->writephyindepconfig(&pd, ®initdata);
|
||||
}
|
||||
if (!status) {
|
||||
status = driverdt->writephyconfig(&pd, ®initdata);
|
||||
}
|
||||
if (status) {
|
||||
printf(" ERROR: LPDDR4_HardwareRegInit failed!!\n");
|
||||
hang();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void j721e_lpddr4_start(void)
|
||||
{
|
||||
uint32_t status = 0U;
|
||||
uint32_t regval = 0U;
|
||||
uint32_t offset = 0U;
|
||||
|
||||
TH_OFFSET_FROM_REG(LPDDR4__START__REG, CTL_SHIFT, offset);
|
||||
|
||||
status = driverdt->readreg(&pd, LPDDR4_CTL_REGS, offset, ®val);
|
||||
if ((status > 0U) || ((regval & TH_FLD_MASK(LPDDR4__START__FLD)) != 0U)) {
|
||||
printf("LPDDR4_StartTest: FAIL\n");
|
||||
hang();
|
||||
}
|
||||
|
||||
status = driverdt->start(&pd);
|
||||
if (status > 0U) {
|
||||
printf("LPDDR4_StartTest: FAIL\n");
|
||||
hang();
|
||||
}
|
||||
|
||||
status = driverdt->readreg(&pd, LPDDR4_CTL_REGS, offset, ®val);
|
||||
if ((status > 0U) || ((regval & TH_FLD_MASK(LPDDR4__START__FLD)) != 1U)) {
|
||||
printf("LPDDR4_Start: FAIL\n");
|
||||
hang();
|
||||
} else {
|
||||
debug("LPDDR4_Start: PASS\n");
|
||||
}
|
||||
}
|
||||
|
||||
static int j721e_ddrss_probe(struct udevice *dev)
|
||||
{
|
||||
int ret;
|
||||
ddrss = dev_get_priv(dev);
|
||||
|
||||
debug("%s(dev=%p)\n", __func__, dev);
|
||||
|
||||
ret = j721e_ddrss_ofdata_to_priv(dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ddrss->dev = dev;
|
||||
ret = j721e_ddrss_power_on(ddrss);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
driverdt = lpddr4_getinstance();
|
||||
j721e_lpddr4_probe();
|
||||
j721e_lpddr4_init();
|
||||
j721e_lpddr4_hardware_reg_init();
|
||||
j721e_lpddr4_start();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int j721e_ddrss_get_info(struct udevice *dev, struct ram_info *info)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct ram_ops j721e_ddrss_ops = {
|
||||
.get_info = j721e_ddrss_get_info,
|
||||
};
|
||||
|
||||
static const struct udevice_id j721e_ddrss_ids[] = {
|
||||
{.compatible = "ti,j721e-ddrss"},
|
||||
{}
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(j721e_ddrss) = {
|
||||
.name = "j721e_ddrss",
|
||||
.id = UCLASS_RAM,
|
||||
.of_match = j721e_ddrss_ids,
|
||||
.ops = &j721e_ddrss_ops,
|
||||
.probe = j721e_ddrss_probe,
|
||||
.priv_auto_alloc_size = sizeof(struct j721e_ddrss_desc),
|
||||
};
|
||||
File diff suppressed because it is too large
Load Diff
+825
@@ -0,0 +1,825 @@
|
||||
/* SPDX-License-Identifier: BSD-3-Clause */
|
||||
/**********************************************************************
|
||||
* Copyright (C) 2012-2019 Cadence Design Systems, Inc.
|
||||
*
|
||||
* THIS FILE IS AUTOMATICALLY GENERATED, DO NOT EDIT
|
||||
*
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
#ifndef REG_LPDDR4_ADDRESS_SLICE_0_MACROS_H_
|
||||
#define REG_LPDDR4_ADDRESS_SLICE_0_MACROS_H_
|
||||
|
||||
#define LPDDR4__DENALI_PHY_1024_READ_MASK 0x000107FFU
|
||||
#define LPDDR4__DENALI_PHY_1024_WRITE_MASK 0x000107FFU
|
||||
#define LPDDR4__DENALI_PHY_1024__PHY_ADR_CLK_WR_BYPASS_SLAVE_DELAY_0_MASK 0x000007FFU
|
||||
#define LPDDR4__DENALI_PHY_1024__PHY_ADR_CLK_WR_BYPASS_SLAVE_DELAY_0_SHIFT 0U
|
||||
#define LPDDR4__DENALI_PHY_1024__PHY_ADR_CLK_WR_BYPASS_SLAVE_DELAY_0_WIDTH 11U
|
||||
#define LPDDR4__PHY_ADR_CLK_WR_BYPASS_SLAVE_DELAY_0__REG DENALI_PHY_1024
|
||||
#define LPDDR4__PHY_ADR_CLK_WR_BYPASS_SLAVE_DELAY_0__FLD LPDDR4__DENALI_PHY_1024__PHY_ADR_CLK_WR_BYPASS_SLAVE_DELAY_0
|
||||
|
||||
#define LPDDR4__DENALI_PHY_1024__PHY_ADR_CLK_BYPASS_OVERRIDE_0_MASK 0x00010000U
|
||||
#define LPDDR4__DENALI_PHY_1024__PHY_ADR_CLK_BYPASS_OVERRIDE_0_SHIFT 16U
|
||||
#define LPDDR4__DENALI_PHY_1024__PHY_ADR_CLK_BYPASS_OVERRIDE_0_WIDTH 1U
|
||||
#define LPDDR4__DENALI_PHY_1024__PHY_ADR_CLK_BYPASS_OVERRIDE_0_WOCLR 0U
|
||||
#define LPDDR4__DENALI_PHY_1024__PHY_ADR_CLK_BYPASS_OVERRIDE_0_WOSET 0U
|
||||
#define LPDDR4__PHY_ADR_CLK_BYPASS_OVERRIDE_0__REG DENALI_PHY_1024
|
||||
#define LPDDR4__PHY_ADR_CLK_BYPASS_OVERRIDE_0__FLD LPDDR4__DENALI_PHY_1024__PHY_ADR_CLK_BYPASS_OVERRIDE_0
|
||||
|
||||
#define LPDDR4__DENALI_PHY_1024__SC_PHY_ADR_MANUAL_CLEAR_0_MASK 0x07000000U
|
||||
#define LPDDR4__DENALI_PHY_1024__SC_PHY_ADR_MANUAL_CLEAR_0_SHIFT 24U
|
||||
#define LPDDR4__DENALI_PHY_1024__SC_PHY_ADR_MANUAL_CLEAR_0_WIDTH 3U
|
||||
#define LPDDR4__SC_PHY_ADR_MANUAL_CLEAR_0__REG DENALI_PHY_1024
|
||||
#define LPDDR4__SC_PHY_ADR_MANUAL_CLEAR_0__FLD LPDDR4__DENALI_PHY_1024__SC_PHY_ADR_MANUAL_CLEAR_0
|
||||
|
||||
#define LPDDR4__DENALI_PHY_1025_READ_MASK 0xFFFFFFFFU
|
||||
#define LPDDR4__DENALI_PHY_1025_WRITE_MASK 0xFFFFFFFFU
|
||||
#define LPDDR4__DENALI_PHY_1025__PHY_ADR_LPBK_RESULT_OBS_0_MASK 0xFFFFFFFFU
|
||||
#define LPDDR4__DENALI_PHY_1025__PHY_ADR_LPBK_RESULT_OBS_0_SHIFT 0U
|
||||
#define LPDDR4__DENALI_PHY_1025__PHY_ADR_LPBK_RESULT_OBS_0_WIDTH 32U
|
||||
#define LPDDR4__PHY_ADR_LPBK_RESULT_OBS_0__REG DENALI_PHY_1025
|
||||
#define LPDDR4__PHY_ADR_LPBK_RESULT_OBS_0__FLD LPDDR4__DENALI_PHY_1025__PHY_ADR_LPBK_RESULT_OBS_0
|
||||
|
||||
#define LPDDR4__DENALI_PHY_1026_READ_MASK 0x0FFFFFFFU
|
||||
#define LPDDR4__DENALI_PHY_1026_WRITE_MASK 0x0FFFFFFFU
|
||||
#define LPDDR4__DENALI_PHY_1026__PHY_ADR_LPBK_ERROR_COUNT_OBS_0_MASK 0x0000FFFFU
|
||||
#define LPDDR4__DENALI_PHY_1026__PHY_ADR_LPBK_ERROR_COUNT_OBS_0_SHIFT 0U
|
||||
#define LPDDR4__DENALI_PHY_1026__PHY_ADR_LPBK_ERROR_COUNT_OBS_0_WIDTH 16U
|
||||
#define LPDDR4__PHY_ADR_LPBK_ERROR_COUNT_OBS_0__REG DENALI_PHY_1026
|
||||
#define LPDDR4__PHY_ADR_LPBK_ERROR_COUNT_OBS_0__FLD LPDDR4__DENALI_PHY_1026__PHY_ADR_LPBK_ERROR_COUNT_OBS_0
|
||||
|
||||
#define LPDDR4__DENALI_PHY_1026__PHY_ADR_MEAS_DLY_STEP_VALUE_0_MASK 0x00FF0000U
|
||||
#define LPDDR4__DENALI_PHY_1026__PHY_ADR_MEAS_DLY_STEP_VALUE_0_SHIFT 16U
|
||||
#define LPDDR4__DENALI_PHY_1026__PHY_ADR_MEAS_DLY_STEP_VALUE_0_WIDTH 8U
|
||||
#define LPDDR4__PHY_ADR_MEAS_DLY_STEP_VALUE_0__REG DENALI_PHY_1026
|
||||
#define LPDDR4__PHY_ADR_MEAS_DLY_STEP_VALUE_0__FLD LPDDR4__DENALI_PHY_1026__PHY_ADR_MEAS_DLY_STEP_VALUE_0
|
||||
|
||||
#define LPDDR4__DENALI_PHY_1026__PHY_ADR_MASTER_DLY_LOCK_OBS_SELECT_0_MASK 0x0F000000U
|
||||
#define LPDDR4__DENALI_PHY_1026__PHY_ADR_MASTER_DLY_LOCK_OBS_SELECT_0_SHIFT 24U
|
||||
#define LPDDR4__DENALI_PHY_1026__PHY_ADR_MASTER_DLY_LOCK_OBS_SELECT_0_WIDTH 4U
|
||||
#define LPDDR4__PHY_ADR_MASTER_DLY_LOCK_OBS_SELECT_0__REG DENALI_PHY_1026
|
||||
#define LPDDR4__PHY_ADR_MASTER_DLY_LOCK_OBS_SELECT_0__FLD LPDDR4__DENALI_PHY_1026__PHY_ADR_MASTER_DLY_LOCK_OBS_SELECT_0
|
||||
|
||||
#define LPDDR4__DENALI_PHY_1027_READ_MASK 0xFF7F07FFU
|
||||
#define LPDDR4__DENALI_PHY_1027_WRITE_MASK 0xFF7F07FFU
|
||||
#define LPDDR4__DENALI_PHY_1027__PHY_ADR_MASTER_DLY_LOCK_OBS_0_MASK 0x000007FFU
|
||||
#define LPDDR4__DENALI_PHY_1027__PHY_ADR_MASTER_DLY_LOCK_OBS_0_SHIFT 0U
|
||||
#define LPDDR4__DENALI_PHY_1027__PHY_ADR_MASTER_DLY_LOCK_OBS_0_WIDTH 11U
|
||||
#define LPDDR4__PHY_ADR_MASTER_DLY_LOCK_OBS_0__REG DENALI_PHY_1027
|
||||
#define LPDDR4__PHY_ADR_MASTER_DLY_LOCK_OBS_0__FLD LPDDR4__DENALI_PHY_1027__PHY_ADR_MASTER_DLY_LOCK_OBS_0
|
||||
|
||||
#define LPDDR4__DENALI_PHY_1027__PHY_ADR_BASE_SLV_DLY_ENC_OBS_0_MASK 0x007F0000U
|
||||
#define LPDDR4__DENALI_PHY_1027__PHY_ADR_BASE_SLV_DLY_ENC_OBS_0_SHIFT 16U
|
||||
#define LPDDR4__DENALI_PHY_1027__PHY_ADR_BASE_SLV_DLY_ENC_OBS_0_WIDTH 7U
|
||||
#define LPDDR4__PHY_ADR_BASE_SLV_DLY_ENC_OBS_0__REG DENALI_PHY_1027
|
||||
#define LPDDR4__PHY_ADR_BASE_SLV_DLY_ENC_OBS_0__FLD LPDDR4__DENALI_PHY_1027__PHY_ADR_BASE_SLV_DLY_ENC_OBS_0
|
||||
|
||||
#define LPDDR4__DENALI_PHY_1027__PHY_ADR_ADDER_SLV_DLY_ENC_OBS_0_MASK 0xFF000000U
|
||||
#define LPDDR4__DENALI_PHY_1027__PHY_ADR_ADDER_SLV_DLY_ENC_OBS_0_SHIFT 24U
|
||||
#define LPDDR4__DENALI_PHY_1027__PHY_ADR_ADDER_SLV_DLY_ENC_OBS_0_WIDTH 8U
|
||||
#define LPDDR4__PHY_ADR_ADDER_SLV_DLY_ENC_OBS_0__REG DENALI_PHY_1027
|
||||
#define LPDDR4__PHY_ADR_ADDER_SLV_DLY_ENC_OBS_0__FLD LPDDR4__DENALI_PHY_1027__PHY_ADR_ADDER_SLV_DLY_ENC_OBS_0
|
||||
|
||||
#define LPDDR4__DENALI_PHY_1028_READ_MASK 0x01000707U
|
||||
#define LPDDR4__DENALI_PHY_1028_WRITE_MASK 0x01000707U
|
||||
#define LPDDR4__DENALI_PHY_1028__PHY_ADR_SLAVE_LOOP_CNT_UPDATE_0_MASK 0x00000007U
|
||||
#define LPDDR4__DENALI_PHY_1028__PHY_ADR_SLAVE_LOOP_CNT_UPDATE_0_SHIFT 0U
|
||||
#define LPDDR4__DENALI_PHY_1028__PHY_ADR_SLAVE_LOOP_CNT_UPDATE_0_WIDTH 3U
|
||||
#define LPDDR4__PHY_ADR_SLAVE_LOOP_CNT_UPDATE_0__REG DENALI_PHY_1028
|
||||
#define LPDDR4__PHY_ADR_SLAVE_LOOP_CNT_UPDATE_0__FLD LPDDR4__DENALI_PHY_1028__PHY_ADR_SLAVE_LOOP_CNT_UPDATE_0
|
||||
|
||||
#define LPDDR4__DENALI_PHY_1028__PHY_ADR_SLV_DLY_ENC_OBS_SELECT_0_MASK 0x00000700U
|
||||
#define LPDDR4__DENALI_PHY_1028__PHY_ADR_SLV_DLY_ENC_OBS_SELECT_0_SHIFT 8U
|
||||
#define LPDDR4__DENALI_PHY_1028__PHY_ADR_SLV_DLY_ENC_OBS_SELECT_0_WIDTH 3U
|
||||
#define LPDDR4__PHY_ADR_SLV_DLY_ENC_OBS_SELECT_0__REG DENALI_PHY_1028
|
||||
#define LPDDR4__PHY_ADR_SLV_DLY_ENC_OBS_SELECT_0__FLD LPDDR4__DENALI_PHY_1028__PHY_ADR_SLV_DLY_ENC_OBS_SELECT_0
|
||||
|
||||
#define LPDDR4__DENALI_PHY_1028__SC_PHY_ADR_SNAP_OBS_REGS_0_MASK 0x00010000U
|
||||
#define LPDDR4__DENALI_PHY_1028__SC_PHY_ADR_SNAP_OBS_REGS_0_SHIFT 16U
|
||||
#define LPDDR4__DENALI_PHY_1028__SC_PHY_ADR_SNAP_OBS_REGS_0_WIDTH 1U
|
||||
#define LPDDR4__DENALI_PHY_1028__SC_PHY_ADR_SNAP_OBS_REGS_0_WOCLR 0U
|
||||
#define LPDDR4__DENALI_PHY_1028__SC_PHY_ADR_SNAP_OBS_REGS_0_WOSET 0U
|
||||
#define LPDDR4__SC_PHY_ADR_SNAP_OBS_REGS_0__REG DENALI_PHY_1028
|
||||
#define LPDDR4__SC_PHY_ADR_SNAP_OBS_REGS_0__FLD LPDDR4__DENALI_PHY_1028__SC_PHY_ADR_SNAP_OBS_REGS_0
|
||||
|
||||
#define LPDDR4__DENALI_PHY_1028__PHY_ADR_TSEL_ENABLE_0_MASK 0x01000000U
|
||||
#define LPDDR4__DENALI_PHY_1028__PHY_ADR_TSEL_ENABLE_0_SHIFT 24U
|
||||
#define LPDDR4__DENALI_PHY_1028__PHY_ADR_TSEL_ENABLE_0_WIDTH 1U
|
||||
#define LPDDR4__DENALI_PHY_1028__PHY_ADR_TSEL_ENABLE_0_WOCLR 0U
|
||||
#define LPDDR4__DENALI_PHY_1028__PHY_ADR_TSEL_ENABLE_0_WOSET 0U
|
||||
#define LPDDR4__PHY_ADR_TSEL_ENABLE_0__REG DENALI_PHY_1028
|
||||
#define LPDDR4__PHY_ADR_TSEL_ENABLE_0__FLD LPDDR4__DENALI_PHY_1028__PHY_ADR_TSEL_ENABLE_0
|
||||
|
||||
#define LPDDR4__DENALI_PHY_1029_READ_MASK 0x011F7F7FU
|
||||
#define LPDDR4__DENALI_PHY_1029_WRITE_MASK 0x011F7F7FU
|
||||
#define LPDDR4__DENALI_PHY_1029__PHY_ADR_LPBK_CONTROL_0_MASK 0x0000007FU
|
||||
#define LPDDR4__DENALI_PHY_1029__PHY_ADR_LPBK_CONTROL_0_SHIFT 0U
|
||||
#define LPDDR4__DENALI_PHY_1029__PHY_ADR_LPBK_CONTROL_0_WIDTH 7U
|
||||
#define LPDDR4__PHY_ADR_LPBK_CONTROL_0__REG DENALI_PHY_1029
|
||||
#define LPDDR4__PHY_ADR_LPBK_CONTROL_0__FLD LPDDR4__DENALI_PHY_1029__PHY_ADR_LPBK_CONTROL_0
|
||||
|
||||
#define LPDDR4__DENALI_PHY_1029__PHY_ADR_PRBS_PATTERN_START_0_MASK 0x00007F00U
|
||||
#define LPDDR4__DENALI_PHY_1029__PHY_ADR_PRBS_PATTERN_START_0_SHIFT 8U
|
||||
#define LPDDR4__DENALI_PHY_1029__PHY_ADR_PRBS_PATTERN_START_0_WIDTH 7U
|
||||
#define LPDDR4__PHY_ADR_PRBS_PATTERN_START_0__REG DENALI_PHY_1029
|
||||
#define LPDDR4__PHY_ADR_PRBS_PATTERN_START_0__FLD LPDDR4__DENALI_PHY_1029__PHY_ADR_PRBS_PATTERN_START_0
|
||||
|
||||
#define LPDDR4__DENALI_PHY_1029__PHY_ADR_PRBS_PATTERN_MASK_0_MASK 0x001F0000U
|
||||
#define LPDDR4__DENALI_PHY_1029__PHY_ADR_PRBS_PATTERN_MASK_0_SHIFT 16U
|
||||
#define LPDDR4__DENALI_PHY_1029__PHY_ADR_PRBS_PATTERN_MASK_0_WIDTH 5U
|
||||
#define LPDDR4__PHY_ADR_PRBS_PATTERN_MASK_0__REG DENALI_PHY_1029
|
||||
#define LPDDR4__PHY_ADR_PRBS_PATTERN_MASK_0__FLD LPDDR4__DENALI_PHY_1029__PHY_ADR_PRBS_PATTERN_MASK_0
|
||||
|
||||
#define LPDDR4__DENALI_PHY_1029__PHY_ADR_PWR_RDC_DISABLE_0_MASK 0x01000000U
|
||||
#define LPDDR4__DENALI_PHY_1029__PHY_ADR_PWR_RDC_DISABLE_0_SHIFT 24U
|
||||
#define LPDDR4__DENALI_PHY_1029__PHY_ADR_PWR_RDC_DISABLE_0_WIDTH 1U
|
||||
#define LPDDR4__DENALI_PHY_1029__PHY_ADR_PWR_RDC_DISABLE_0_WOCLR 0U
|
||||
#define LPDDR4__DENALI_PHY_1029__PHY_ADR_PWR_RDC_DISABLE_0_WOSET 0U
|
||||
#define LPDDR4__PHY_ADR_PWR_RDC_DISABLE_0__REG DENALI_PHY_1029
|
||||
#define LPDDR4__PHY_ADR_PWR_RDC_DISABLE_0__FLD LPDDR4__DENALI_PHY_1029__PHY_ADR_PWR_RDC_DISABLE_0
|
||||
|
||||
#define LPDDR4__DENALI_PHY_1030_READ_MASK 0x01070301U
|
||||
#define LPDDR4__DENALI_PHY_1030_WRITE_MASK 0x01070301U
|
||||
#define LPDDR4__DENALI_PHY_1030__PHY_ADR_SLV_DLY_CTRL_GATE_DISABLE_0_MASK 0x00000001U
|
||||
#define LPDDR4__DENALI_PHY_1030__PHY_ADR_SLV_DLY_CTRL_GATE_DISABLE_0_SHIFT 0U
|
||||
#define LPDDR4__DENALI_PHY_1030__PHY_ADR_SLV_DLY_CTRL_GATE_DISABLE_0_WIDTH 1U
|
||||
#define LPDDR4__DENALI_PHY_1030__PHY_ADR_SLV_DLY_CTRL_GATE_DISABLE_0_WOCLR 0U
|
||||
#define LPDDR4__DENALI_PHY_1030__PHY_ADR_SLV_DLY_CTRL_GATE_DISABLE_0_WOSET 0U
|
||||
#define LPDDR4__PHY_ADR_SLV_DLY_CTRL_GATE_DISABLE_0__REG DENALI_PHY_1030
|
||||
#define LPDDR4__PHY_ADR_SLV_DLY_CTRL_GATE_DISABLE_0__FLD LPDDR4__DENALI_PHY_1030__PHY_ADR_SLV_DLY_CTRL_GATE_DISABLE_0
|
||||
|
||||
#define LPDDR4__DENALI_PHY_1030__PHY_ADR_TYPE_0_MASK 0x00000300U
|
||||
#define LPDDR4__DENALI_PHY_1030__PHY_ADR_TYPE_0_SHIFT 8U
|
||||
#define LPDDR4__DENALI_PHY_1030__PHY_ADR_TYPE_0_WIDTH 2U
|
||||
#define LPDDR4__PHY_ADR_TYPE_0__REG DENALI_PHY_1030
|
||||
#define LPDDR4__PHY_ADR_TYPE_0__FLD LPDDR4__DENALI_PHY_1030__PHY_ADR_TYPE_0
|
||||
|
||||
#define LPDDR4__DENALI_PHY_1030__PHY_ADR_WRADDR_SHIFT_OBS_0_MASK 0x00070000U
|
||||
#define LPDDR4__DENALI_PHY_1030__PHY_ADR_WRADDR_SHIFT_OBS_0_SHIFT 16U
|
||||
#define LPDDR4__DENALI_PHY_1030__PHY_ADR_WRADDR_SHIFT_OBS_0_WIDTH 3U
|
||||
#define LPDDR4__PHY_ADR_WRADDR_SHIFT_OBS_0__REG DENALI_PHY_1030
|
||||
#define LPDDR4__PHY_ADR_WRADDR_SHIFT_OBS_0__FLD LPDDR4__DENALI_PHY_1030__PHY_ADR_WRADDR_SHIFT_OBS_0
|
||||
|
||||
#define LPDDR4__DENALI_PHY_1030__PHY_ADR_IE_MODE_0_MASK 0x01000000U
|
||||
#define LPDDR4__DENALI_PHY_1030__PHY_ADR_IE_MODE_0_SHIFT 24U
|
||||
#define LPDDR4__DENALI_PHY_1030__PHY_ADR_IE_MODE_0_WIDTH 1U
|
||||
#define LPDDR4__DENALI_PHY_1030__PHY_ADR_IE_MODE_0_WOCLR 0U
|
||||
#define LPDDR4__DENALI_PHY_1030__PHY_ADR_IE_MODE_0_WOSET 0U
|
||||
#define LPDDR4__PHY_ADR_IE_MODE_0__REG DENALI_PHY_1030
|
||||
#define LPDDR4__PHY_ADR_IE_MODE_0__FLD LPDDR4__DENALI_PHY_1030__PHY_ADR_IE_MODE_0
|
||||
|
||||
#define LPDDR4__DENALI_PHY_1031_READ_MASK 0x07FFFFFFU
|
||||
#define LPDDR4__DENALI_PHY_1031_WRITE_MASK 0x07FFFFFFU
|
||||
#define LPDDR4__DENALI_PHY_1031__PHY_ADR_DDL_MODE_0_MASK 0x07FFFFFFU
|
||||
#define LPDDR4__DENALI_PHY_1031__PHY_ADR_DDL_MODE_0_SHIFT 0U
|
||||
#define LPDDR4__DENALI_PHY_1031__PHY_ADR_DDL_MODE_0_WIDTH 27U
|
||||
#define LPDDR4__PHY_ADR_DDL_MODE_0__REG DENALI_PHY_1031
|
||||
#define LPDDR4__PHY_ADR_DDL_MODE_0__FLD LPDDR4__DENALI_PHY_1031__PHY_ADR_DDL_MODE_0
|
||||
|
||||
#define LPDDR4__DENALI_PHY_1032_READ_MASK 0x0000003FU
|
||||
#define LPDDR4__DENALI_PHY_1032_WRITE_MASK 0x0000003FU
|
||||
#define LPDDR4__DENALI_PHY_1032__PHY_ADR_DDL_MASK_0_MASK 0x0000003FU
|
||||
#define LPDDR4__DENALI_PHY_1032__PHY_ADR_DDL_MASK_0_SHIFT 0U
|
||||
#define LPDDR4__DENALI_PHY_1032__PHY_ADR_DDL_MASK_0_WIDTH 6U
|
||||
#define LPDDR4__PHY_ADR_DDL_MASK_0__REG DENALI_PHY_1032
|
||||
#define LPDDR4__PHY_ADR_DDL_MASK_0__FLD LPDDR4__DENALI_PHY_1032__PHY_ADR_DDL_MASK_0
|
||||
|
||||
#define LPDDR4__DENALI_PHY_1033_READ_MASK 0xFFFFFFFFU
|
||||
#define LPDDR4__DENALI_PHY_1033_WRITE_MASK 0xFFFFFFFFU
|
||||
#define LPDDR4__DENALI_PHY_1033__PHY_ADR_DDL_TEST_OBS_0_MASK 0xFFFFFFFFU
|
||||
#define LPDDR4__DENALI_PHY_1033__PHY_ADR_DDL_TEST_OBS_0_SHIFT 0U
|
||||
#define LPDDR4__DENALI_PHY_1033__PHY_ADR_DDL_TEST_OBS_0_WIDTH 32U
|
||||
#define LPDDR4__PHY_ADR_DDL_TEST_OBS_0__REG DENALI_PHY_1033
|
||||
#define LPDDR4__PHY_ADR_DDL_TEST_OBS_0__FLD LPDDR4__DENALI_PHY_1033__PHY_ADR_DDL_TEST_OBS_0
|
||||
|
||||
#define LPDDR4__DENALI_PHY_1034_READ_MASK 0xFFFFFFFFU
|
||||
#define LPDDR4__DENALI_PHY_1034_WRITE_MASK 0xFFFFFFFFU
|
||||
#define LPDDR4__DENALI_PHY_1034__PHY_ADR_DDL_TEST_MSTR_DLY_OBS_0_MASK 0xFFFFFFFFU
|
||||
#define LPDDR4__DENALI_PHY_1034__PHY_ADR_DDL_TEST_MSTR_DLY_OBS_0_SHIFT 0U
|
||||
#define LPDDR4__DENALI_PHY_1034__PHY_ADR_DDL_TEST_MSTR_DLY_OBS_0_WIDTH 32U
|
||||
#define LPDDR4__PHY_ADR_DDL_TEST_MSTR_DLY_OBS_0__REG DENALI_PHY_1034
|
||||
#define LPDDR4__PHY_ADR_DDL_TEST_MSTR_DLY_OBS_0__FLD LPDDR4__DENALI_PHY_1034__PHY_ADR_DDL_TEST_MSTR_DLY_OBS_0
|
||||
|
||||
#define LPDDR4__DENALI_PHY_1035_READ_MASK 0x07FF07FFU
|
||||
#define LPDDR4__DENALI_PHY_1035_WRITE_MASK 0x07FF07FFU
|
||||
#define LPDDR4__DENALI_PHY_1035__PHY_ADR_CALVL_START_0_MASK 0x000007FFU
|
||||
#define LPDDR4__DENALI_PHY_1035__PHY_ADR_CALVL_START_0_SHIFT 0U
|
||||
#define LPDDR4__DENALI_PHY_1035__PHY_ADR_CALVL_START_0_WIDTH 11U
|
||||
#define LPDDR4__PHY_ADR_CALVL_START_0__REG DENALI_PHY_1035
|
||||
#define LPDDR4__PHY_ADR_CALVL_START_0__FLD LPDDR4__DENALI_PHY_1035__PHY_ADR_CALVL_START_0
|
||||
|
||||
#define LPDDR4__DENALI_PHY_1035__PHY_ADR_CALVL_COARSE_DLY_0_MASK 0x07FF0000U
|
||||
#define LPDDR4__DENALI_PHY_1035__PHY_ADR_CALVL_COARSE_DLY_0_SHIFT 16U
|
||||
#define LPDDR4__DENALI_PHY_1035__PHY_ADR_CALVL_COARSE_DLY_0_WIDTH 11U
|
||||
#define LPDDR4__PHY_ADR_CALVL_COARSE_DLY_0__REG DENALI_PHY_1035
|
||||
#define LPDDR4__PHY_ADR_CALVL_COARSE_DLY_0__FLD LPDDR4__DENALI_PHY_1035__PHY_ADR_CALVL_COARSE_DLY_0
|
||||
|
||||
#define LPDDR4__DENALI_PHY_1036_READ_MASK 0x000007FFU
|
||||
#define LPDDR4__DENALI_PHY_1036_WRITE_MASK 0x000007FFU
|
||||
#define LPDDR4__DENALI_PHY_1036__PHY_ADR_CALVL_QTR_0_MASK 0x000007FFU
|
||||
#define LPDDR4__DENALI_PHY_1036__PHY_ADR_CALVL_QTR_0_SHIFT 0U
|
||||
#define LPDDR4__DENALI_PHY_1036__PHY_ADR_CALVL_QTR_0_WIDTH 11U
|
||||
#define LPDDR4__PHY_ADR_CALVL_QTR_0__REG DENALI_PHY_1036
|
||||
#define LPDDR4__PHY_ADR_CALVL_QTR_0__FLD LPDDR4__DENALI_PHY_1036__PHY_ADR_CALVL_QTR_0
|
||||
|
||||
#define LPDDR4__DENALI_PHY_1037_READ_MASK 0x00FFFFFFU
|
||||
#define LPDDR4__DENALI_PHY_1037_WRITE_MASK 0x00FFFFFFU
|
||||
#define LPDDR4__DENALI_PHY_1037__PHY_ADR_CALVL_SWIZZLE0_0_MASK 0x00FFFFFFU
|
||||
#define LPDDR4__DENALI_PHY_1037__PHY_ADR_CALVL_SWIZZLE0_0_SHIFT 0U
|
||||
#define LPDDR4__DENALI_PHY_1037__PHY_ADR_CALVL_SWIZZLE0_0_WIDTH 24U
|
||||
#define LPDDR4__PHY_ADR_CALVL_SWIZZLE0_0__REG DENALI_PHY_1037
|
||||
#define LPDDR4__PHY_ADR_CALVL_SWIZZLE0_0__FLD LPDDR4__DENALI_PHY_1037__PHY_ADR_CALVL_SWIZZLE0_0
|
||||
|
||||
#define LPDDR4__DENALI_PHY_1038_READ_MASK 0x03FFFFFFU
|
||||
#define LPDDR4__DENALI_PHY_1038_WRITE_MASK 0x03FFFFFFU
|
||||
#define LPDDR4__DENALI_PHY_1038__PHY_ADR_CALVL_SWIZZLE1_0_MASK 0x00FFFFFFU
|
||||
#define LPDDR4__DENALI_PHY_1038__PHY_ADR_CALVL_SWIZZLE1_0_SHIFT 0U
|
||||
#define LPDDR4__DENALI_PHY_1038__PHY_ADR_CALVL_SWIZZLE1_0_WIDTH 24U
|
||||
#define LPDDR4__PHY_ADR_CALVL_SWIZZLE1_0__REG DENALI_PHY_1038
|
||||
#define LPDDR4__PHY_ADR_CALVL_SWIZZLE1_0__FLD LPDDR4__DENALI_PHY_1038__PHY_ADR_CALVL_SWIZZLE1_0
|
||||
|
||||
#define LPDDR4__DENALI_PHY_1038__PHY_ADR_CALVL_RANK_CTRL_0_MASK 0x03000000U
|
||||
#define LPDDR4__DENALI_PHY_1038__PHY_ADR_CALVL_RANK_CTRL_0_SHIFT 24U
|
||||
#define LPDDR4__DENALI_PHY_1038__PHY_ADR_CALVL_RANK_CTRL_0_WIDTH 2U
|
||||
#define LPDDR4__PHY_ADR_CALVL_RANK_CTRL_0__REG DENALI_PHY_1038
|
||||
#define LPDDR4__PHY_ADR_CALVL_RANK_CTRL_0__FLD LPDDR4__DENALI_PHY_1038__PHY_ADR_CALVL_RANK_CTRL_0
|
||||
|
||||
#define LPDDR4__DENALI_PHY_1039_READ_MASK 0x01FF0F03U
|
||||
#define LPDDR4__DENALI_PHY_1039_WRITE_MASK 0x01FF0F03U
|
||||
#define LPDDR4__DENALI_PHY_1039__PHY_ADR_CALVL_NUM_PATTERNS_0_MASK 0x00000003U
|
||||
#define LPDDR4__DENALI_PHY_1039__PHY_ADR_CALVL_NUM_PATTERNS_0_SHIFT 0U
|
||||
#define LPDDR4__DENALI_PHY_1039__PHY_ADR_CALVL_NUM_PATTERNS_0_WIDTH 2U
|
||||
#define LPDDR4__PHY_ADR_CALVL_NUM_PATTERNS_0__REG DENALI_PHY_1039
|
||||
#define LPDDR4__PHY_ADR_CALVL_NUM_PATTERNS_0__FLD LPDDR4__DENALI_PHY_1039__PHY_ADR_CALVL_NUM_PATTERNS_0
|
||||
|
||||
#define LPDDR4__DENALI_PHY_1039__PHY_ADR_CALVL_RESP_WAIT_CNT_0_MASK 0x00000F00U
|
||||
#define LPDDR4__DENALI_PHY_1039__PHY_ADR_CALVL_RESP_WAIT_CNT_0_SHIFT 8U
|
||||
#define LPDDR4__DENALI_PHY_1039__PHY_ADR_CALVL_RESP_WAIT_CNT_0_WIDTH 4U
|
||||
#define LPDDR4__PHY_ADR_CALVL_RESP_WAIT_CNT_0__REG DENALI_PHY_1039
|
||||
#define LPDDR4__PHY_ADR_CALVL_RESP_WAIT_CNT_0__FLD LPDDR4__DENALI_PHY_1039__PHY_ADR_CALVL_RESP_WAIT_CNT_0
|
||||
|
||||
#define LPDDR4__DENALI_PHY_1039__PHY_ADR_CALVL_PERIODIC_START_OFFSET_0_MASK 0x01FF0000U
|
||||
#define LPDDR4__DENALI_PHY_1039__PHY_ADR_CALVL_PERIODIC_START_OFFSET_0_SHIFT 16U
|
||||
#define LPDDR4__DENALI_PHY_1039__PHY_ADR_CALVL_PERIODIC_START_OFFSET_0_WIDTH 9U
|
||||
#define LPDDR4__PHY_ADR_CALVL_PERIODIC_START_OFFSET_0__REG DENALI_PHY_1039
|
||||
#define LPDDR4__PHY_ADR_CALVL_PERIODIC_START_OFFSET_0__FLD LPDDR4__DENALI_PHY_1039__PHY_ADR_CALVL_PERIODIC_START_OFFSET_0
|
||||
|
||||
#define LPDDR4__DENALI_PHY_1040_READ_MASK 0x07000001U
|
||||
#define LPDDR4__DENALI_PHY_1040_WRITE_MASK 0x07000001U
|
||||
#define LPDDR4__DENALI_PHY_1040__PHY_ADR_CALVL_DEBUG_MODE_0_MASK 0x00000001U
|
||||
#define LPDDR4__DENALI_PHY_1040__PHY_ADR_CALVL_DEBUG_MODE_0_SHIFT 0U
|
||||
#define LPDDR4__DENALI_PHY_1040__PHY_ADR_CALVL_DEBUG_MODE_0_WIDTH 1U
|
||||
#define LPDDR4__DENALI_PHY_1040__PHY_ADR_CALVL_DEBUG_MODE_0_WOCLR 0U
|
||||
#define LPDDR4__DENALI_PHY_1040__PHY_ADR_CALVL_DEBUG_MODE_0_WOSET 0U
|
||||
#define LPDDR4__PHY_ADR_CALVL_DEBUG_MODE_0__REG DENALI_PHY_1040
|
||||
#define LPDDR4__PHY_ADR_CALVL_DEBUG_MODE_0__FLD LPDDR4__DENALI_PHY_1040__PHY_ADR_CALVL_DEBUG_MODE_0
|
||||
|
||||
#define LPDDR4__DENALI_PHY_1040__SC_PHY_ADR_CALVL_DEBUG_CONT_0_MASK 0x00000100U
|
||||
#define LPDDR4__DENALI_PHY_1040__SC_PHY_ADR_CALVL_DEBUG_CONT_0_SHIFT 8U
|
||||
#define LPDDR4__DENALI_PHY_1040__SC_PHY_ADR_CALVL_DEBUG_CONT_0_WIDTH 1U
|
||||
#define LPDDR4__DENALI_PHY_1040__SC_PHY_ADR_CALVL_DEBUG_CONT_0_WOCLR 0U
|
||||
#define LPDDR4__DENALI_PHY_1040__SC_PHY_ADR_CALVL_DEBUG_CONT_0_WOSET 0U
|
||||
#define LPDDR4__SC_PHY_ADR_CALVL_DEBUG_CONT_0__REG DENALI_PHY_1040
|
||||
#define LPDDR4__SC_PHY_ADR_CALVL_DEBUG_CONT_0__FLD LPDDR4__DENALI_PHY_1040__SC_PHY_ADR_CALVL_DEBUG_CONT_0
|
||||
|
||||
#define LPDDR4__DENALI_PHY_1040__SC_PHY_ADR_CALVL_ERROR_CLR_0_MASK 0x00010000U
|
||||
#define LPDDR4__DENALI_PHY_1040__SC_PHY_ADR_CALVL_ERROR_CLR_0_SHIFT 16U
|
||||
#define LPDDR4__DENALI_PHY_1040__SC_PHY_ADR_CALVL_ERROR_CLR_0_WIDTH 1U
|
||||
#define LPDDR4__DENALI_PHY_1040__SC_PHY_ADR_CALVL_ERROR_CLR_0_WOCLR 0U
|
||||
#define LPDDR4__DENALI_PHY_1040__SC_PHY_ADR_CALVL_ERROR_CLR_0_WOSET 0U
|
||||
#define LPDDR4__SC_PHY_ADR_CALVL_ERROR_CLR_0__REG DENALI_PHY_1040
|
||||
#define LPDDR4__SC_PHY_ADR_CALVL_ERROR_CLR_0__FLD LPDDR4__DENALI_PHY_1040__SC_PHY_ADR_CALVL_ERROR_CLR_0
|
||||
|
||||
#define LPDDR4__DENALI_PHY_1040__PHY_ADR_CALVL_OBS_SELECT_0_MASK 0x07000000U
|
||||
#define LPDDR4__DENALI_PHY_1040__PHY_ADR_CALVL_OBS_SELECT_0_SHIFT 24U
|
||||
#define LPDDR4__DENALI_PHY_1040__PHY_ADR_CALVL_OBS_SELECT_0_WIDTH 3U
|
||||
#define LPDDR4__PHY_ADR_CALVL_OBS_SELECT_0__REG DENALI_PHY_1040
|
||||
#define LPDDR4__PHY_ADR_CALVL_OBS_SELECT_0__FLD LPDDR4__DENALI_PHY_1040__PHY_ADR_CALVL_OBS_SELECT_0
|
||||
|
||||
#define LPDDR4__DENALI_PHY_1041_READ_MASK 0xFFFFFFFFU
|
||||
#define LPDDR4__DENALI_PHY_1041_WRITE_MASK 0xFFFFFFFFU
|
||||
#define LPDDR4__DENALI_PHY_1041__PHY_ADR_CALVL_CH0_OBS0_0_MASK 0xFFFFFFFFU
|
||||
#define LPDDR4__DENALI_PHY_1041__PHY_ADR_CALVL_CH0_OBS0_0_SHIFT 0U
|
||||
#define LPDDR4__DENALI_PHY_1041__PHY_ADR_CALVL_CH0_OBS0_0_WIDTH 32U
|
||||
#define LPDDR4__PHY_ADR_CALVL_CH0_OBS0_0__REG DENALI_PHY_1041
|
||||
#define LPDDR4__PHY_ADR_CALVL_CH0_OBS0_0__FLD LPDDR4__DENALI_PHY_1041__PHY_ADR_CALVL_CH0_OBS0_0
|
||||
|
||||
#define LPDDR4__DENALI_PHY_1042_READ_MASK 0xFFFFFFFFU
|
||||
#define LPDDR4__DENALI_PHY_1042_WRITE_MASK 0xFFFFFFFFU
|
||||
#define LPDDR4__DENALI_PHY_1042__PHY_ADR_CALVL_CH1_OBS0_0_MASK 0xFFFFFFFFU
|
||||
#define LPDDR4__DENALI_PHY_1042__PHY_ADR_CALVL_CH1_OBS0_0_SHIFT 0U
|
||||
#define LPDDR4__DENALI_PHY_1042__PHY_ADR_CALVL_CH1_OBS0_0_WIDTH 32U
|
||||
#define LPDDR4__PHY_ADR_CALVL_CH1_OBS0_0__REG DENALI_PHY_1042
|
||||
#define LPDDR4__PHY_ADR_CALVL_CH1_OBS0_0__FLD LPDDR4__DENALI_PHY_1042__PHY_ADR_CALVL_CH1_OBS0_0
|
||||
|
||||
#define LPDDR4__DENALI_PHY_1043_READ_MASK 0xFFFFFFFFU
|
||||
#define LPDDR4__DENALI_PHY_1043_WRITE_MASK 0xFFFFFFFFU
|
||||
#define LPDDR4__DENALI_PHY_1043__PHY_ADR_CALVL_OBS1_0_MASK 0xFFFFFFFFU
|
||||
#define LPDDR4__DENALI_PHY_1043__PHY_ADR_CALVL_OBS1_0_SHIFT 0U
|
||||
#define LPDDR4__DENALI_PHY_1043__PHY_ADR_CALVL_OBS1_0_WIDTH 32U
|
||||
#define LPDDR4__PHY_ADR_CALVL_OBS1_0__REG DENALI_PHY_1043
|
||||
#define LPDDR4__PHY_ADR_CALVL_OBS1_0__FLD LPDDR4__DENALI_PHY_1043__PHY_ADR_CALVL_OBS1_0
|
||||
|
||||
#define LPDDR4__DENALI_PHY_1044_READ_MASK 0xFFFFFFFFU
|
||||
#define LPDDR4__DENALI_PHY_1044_WRITE_MASK 0xFFFFFFFFU
|
||||
#define LPDDR4__DENALI_PHY_1044__PHY_ADR_CALVL_OBS2_0_MASK 0xFFFFFFFFU
|
||||
#define LPDDR4__DENALI_PHY_1044__PHY_ADR_CALVL_OBS2_0_SHIFT 0U
|
||||
#define LPDDR4__DENALI_PHY_1044__PHY_ADR_CALVL_OBS2_0_WIDTH 32U
|
||||
#define LPDDR4__PHY_ADR_CALVL_OBS2_0__REG DENALI_PHY_1044
|
||||
#define LPDDR4__PHY_ADR_CALVL_OBS2_0__FLD LPDDR4__DENALI_PHY_1044__PHY_ADR_CALVL_OBS2_0
|
||||
|
||||
#define LPDDR4__DENALI_PHY_1045_READ_MASK 0x000FFFFFU
|
||||
#define LPDDR4__DENALI_PHY_1045_WRITE_MASK 0x000FFFFFU
|
||||
#define LPDDR4__DENALI_PHY_1045__PHY_ADR_CALVL_FG_0_0_MASK 0x000FFFFFU
|
||||
#define LPDDR4__DENALI_PHY_1045__PHY_ADR_CALVL_FG_0_0_SHIFT 0U
|
||||
#define LPDDR4__DENALI_PHY_1045__PHY_ADR_CALVL_FG_0_0_WIDTH 20U
|
||||
#define LPDDR4__PHY_ADR_CALVL_FG_0_0__REG DENALI_PHY_1045
|
||||
#define LPDDR4__PHY_ADR_CALVL_FG_0_0__FLD LPDDR4__DENALI_PHY_1045__PHY_ADR_CALVL_FG_0_0
|
||||
|
||||
#define LPDDR4__DENALI_PHY_1046_READ_MASK 0x000FFFFFU
|
||||
#define LPDDR4__DENALI_PHY_1046_WRITE_MASK 0x000FFFFFU
|
||||
#define LPDDR4__DENALI_PHY_1046__PHY_ADR_CALVL_BG_0_0_MASK 0x000FFFFFU
|
||||
#define LPDDR4__DENALI_PHY_1046__PHY_ADR_CALVL_BG_0_0_SHIFT 0U
|
||||
#define LPDDR4__DENALI_PHY_1046__PHY_ADR_CALVL_BG_0_0_WIDTH 20U
|
||||
#define LPDDR4__PHY_ADR_CALVL_BG_0_0__REG DENALI_PHY_1046
|
||||
#define LPDDR4__PHY_ADR_CALVL_BG_0_0__FLD LPDDR4__DENALI_PHY_1046__PHY_ADR_CALVL_BG_0_0
|
||||
|
||||
#define LPDDR4__DENALI_PHY_1047_READ_MASK 0x000FFFFFU
|
||||
#define LPDDR4__DENALI_PHY_1047_WRITE_MASK 0x000FFFFFU
|
||||
#define LPDDR4__DENALI_PHY_1047__PHY_ADR_CALVL_FG_1_0_MASK 0x000FFFFFU
|
||||
#define LPDDR4__DENALI_PHY_1047__PHY_ADR_CALVL_FG_1_0_SHIFT 0U
|
||||
#define LPDDR4__DENALI_PHY_1047__PHY_ADR_CALVL_FG_1_0_WIDTH 20U
|
||||
#define LPDDR4__PHY_ADR_CALVL_FG_1_0__REG DENALI_PHY_1047
|
||||
#define LPDDR4__PHY_ADR_CALVL_FG_1_0__FLD LPDDR4__DENALI_PHY_1047__PHY_ADR_CALVL_FG_1_0
|
||||
|
||||
#define LPDDR4__DENALI_PHY_1048_READ_MASK 0x000FFFFFU
|
||||
#define LPDDR4__DENALI_PHY_1048_WRITE_MASK 0x000FFFFFU
|
||||
#define LPDDR4__DENALI_PHY_1048__PHY_ADR_CALVL_BG_1_0_MASK 0x000FFFFFU
|
||||
#define LPDDR4__DENALI_PHY_1048__PHY_ADR_CALVL_BG_1_0_SHIFT 0U
|
||||
#define LPDDR4__DENALI_PHY_1048__PHY_ADR_CALVL_BG_1_0_WIDTH 20U
|
||||
#define LPDDR4__PHY_ADR_CALVL_BG_1_0__REG DENALI_PHY_1048
|
||||
#define LPDDR4__PHY_ADR_CALVL_BG_1_0__FLD LPDDR4__DENALI_PHY_1048__PHY_ADR_CALVL_BG_1_0
|
||||
|
||||
#define LPDDR4__DENALI_PHY_1049_READ_MASK 0x000FFFFFU
|
||||
#define LPDDR4__DENALI_PHY_1049_WRITE_MASK 0x000FFFFFU
|
||||
#define LPDDR4__DENALI_PHY_1049__PHY_ADR_CALVL_FG_2_0_MASK 0x000FFFFFU
|
||||
#define LPDDR4__DENALI_PHY_1049__PHY_ADR_CALVL_FG_2_0_SHIFT 0U
|
||||
#define LPDDR4__DENALI_PHY_1049__PHY_ADR_CALVL_FG_2_0_WIDTH 20U
|
||||
#define LPDDR4__PHY_ADR_CALVL_FG_2_0__REG DENALI_PHY_1049
|
||||
#define LPDDR4__PHY_ADR_CALVL_FG_2_0__FLD LPDDR4__DENALI_PHY_1049__PHY_ADR_CALVL_FG_2_0
|
||||
|
||||
#define LPDDR4__DENALI_PHY_1050_READ_MASK 0x000FFFFFU
|
||||
#define LPDDR4__DENALI_PHY_1050_WRITE_MASK 0x000FFFFFU
|
||||
#define LPDDR4__DENALI_PHY_1050__PHY_ADR_CALVL_BG_2_0_MASK 0x000FFFFFU
|
||||
#define LPDDR4__DENALI_PHY_1050__PHY_ADR_CALVL_BG_2_0_SHIFT 0U
|
||||
#define LPDDR4__DENALI_PHY_1050__PHY_ADR_CALVL_BG_2_0_WIDTH 20U
|
||||
#define LPDDR4__PHY_ADR_CALVL_BG_2_0__REG DENALI_PHY_1050
|
||||
#define LPDDR4__PHY_ADR_CALVL_BG_2_0__FLD LPDDR4__DENALI_PHY_1050__PHY_ADR_CALVL_BG_2_0
|
||||
|
||||
#define LPDDR4__DENALI_PHY_1051_READ_MASK 0x000FFFFFU
|
||||
#define LPDDR4__DENALI_PHY_1051_WRITE_MASK 0x000FFFFFU
|
||||
#define LPDDR4__DENALI_PHY_1051__PHY_ADR_CALVL_FG_3_0_MASK 0x000FFFFFU
|
||||
#define LPDDR4__DENALI_PHY_1051__PHY_ADR_CALVL_FG_3_0_SHIFT 0U
|
||||
#define LPDDR4__DENALI_PHY_1051__PHY_ADR_CALVL_FG_3_0_WIDTH 20U
|
||||
#define LPDDR4__PHY_ADR_CALVL_FG_3_0__REG DENALI_PHY_1051
|
||||
#define LPDDR4__PHY_ADR_CALVL_FG_3_0__FLD LPDDR4__DENALI_PHY_1051__PHY_ADR_CALVL_FG_3_0
|
||||
|
||||
#define LPDDR4__DENALI_PHY_1052_READ_MASK 0x000FFFFFU
|
||||
#define LPDDR4__DENALI_PHY_1052_WRITE_MASK 0x000FFFFFU
|
||||
#define LPDDR4__DENALI_PHY_1052__PHY_ADR_CALVL_BG_3_0_MASK 0x000FFFFFU
|
||||
#define LPDDR4__DENALI_PHY_1052__PHY_ADR_CALVL_BG_3_0_SHIFT 0U
|
||||
#define LPDDR4__DENALI_PHY_1052__PHY_ADR_CALVL_BG_3_0_WIDTH 20U
|
||||
#define LPDDR4__PHY_ADR_CALVL_BG_3_0__REG DENALI_PHY_1052
|
||||
#define LPDDR4__PHY_ADR_CALVL_BG_3_0__FLD LPDDR4__DENALI_PHY_1052__PHY_ADR_CALVL_BG_3_0
|
||||
|
||||
#define LPDDR4__DENALI_PHY_1053_READ_MASK 0x00FFFFFFU
|
||||
#define LPDDR4__DENALI_PHY_1053_WRITE_MASK 0x00FFFFFFU
|
||||
#define LPDDR4__DENALI_PHY_1053__PHY_ADR_ADDR_SEL_0_MASK 0x00FFFFFFU
|
||||
#define LPDDR4__DENALI_PHY_1053__PHY_ADR_ADDR_SEL_0_SHIFT 0U
|
||||
#define LPDDR4__DENALI_PHY_1053__PHY_ADR_ADDR_SEL_0_WIDTH 24U
|
||||
#define LPDDR4__PHY_ADR_ADDR_SEL_0__REG DENALI_PHY_1053
|
||||
#define LPDDR4__PHY_ADR_ADDR_SEL_0__FLD LPDDR4__DENALI_PHY_1053__PHY_ADR_ADDR_SEL_0
|
||||
|
||||
#define LPDDR4__DENALI_PHY_1054_READ_MASK 0x3F3F03FFU
|
||||
#define LPDDR4__DENALI_PHY_1054_WRITE_MASK 0x3F3F03FFU
|
||||
#define LPDDR4__DENALI_PHY_1054__PHY_ADR_LP4_BOOT_SLV_DELAY_0_MASK 0x000003FFU
|
||||
#define LPDDR4__DENALI_PHY_1054__PHY_ADR_LP4_BOOT_SLV_DELAY_0_SHIFT 0U
|
||||
#define LPDDR4__DENALI_PHY_1054__PHY_ADR_LP4_BOOT_SLV_DELAY_0_WIDTH 10U
|
||||
#define LPDDR4__PHY_ADR_LP4_BOOT_SLV_DELAY_0__REG DENALI_PHY_1054
|
||||
#define LPDDR4__PHY_ADR_LP4_BOOT_SLV_DELAY_0__FLD LPDDR4__DENALI_PHY_1054__PHY_ADR_LP4_BOOT_SLV_DELAY_0
|
||||
|
||||
#define LPDDR4__DENALI_PHY_1054__PHY_ADR_BIT_MASK_0_MASK 0x003F0000U
|
||||
#define LPDDR4__DENALI_PHY_1054__PHY_ADR_BIT_MASK_0_SHIFT 16U
|
||||
#define LPDDR4__DENALI_PHY_1054__PHY_ADR_BIT_MASK_0_WIDTH 6U
|
||||
#define LPDDR4__PHY_ADR_BIT_MASK_0__REG DENALI_PHY_1054
|
||||
#define LPDDR4__PHY_ADR_BIT_MASK_0__FLD LPDDR4__DENALI_PHY_1054__PHY_ADR_BIT_MASK_0
|
||||
|
||||
#define LPDDR4__DENALI_PHY_1054__PHY_ADR_SEG_MASK_0_MASK 0x3F000000U
|
||||
#define LPDDR4__DENALI_PHY_1054__PHY_ADR_SEG_MASK_0_SHIFT 24U
|
||||
#define LPDDR4__DENALI_PHY_1054__PHY_ADR_SEG_MASK_0_WIDTH 6U
|
||||
#define LPDDR4__PHY_ADR_SEG_MASK_0__REG DENALI_PHY_1054
|
||||
#define LPDDR4__PHY_ADR_SEG_MASK_0__FLD LPDDR4__DENALI_PHY_1054__PHY_ADR_SEG_MASK_0
|
||||
|
||||
#define LPDDR4__DENALI_PHY_1055_READ_MASK 0x3F0F3F3FU
|
||||
#define LPDDR4__DENALI_PHY_1055_WRITE_MASK 0x3F0F3F3FU
|
||||
#define LPDDR4__DENALI_PHY_1055__PHY_ADR_CALVL_TRAIN_MASK_0_MASK 0x0000003FU
|
||||
#define LPDDR4__DENALI_PHY_1055__PHY_ADR_CALVL_TRAIN_MASK_0_SHIFT 0U
|
||||
#define LPDDR4__DENALI_PHY_1055__PHY_ADR_CALVL_TRAIN_MASK_0_WIDTH 6U
|
||||
#define LPDDR4__PHY_ADR_CALVL_TRAIN_MASK_0__REG DENALI_PHY_1055
|
||||
#define LPDDR4__PHY_ADR_CALVL_TRAIN_MASK_0__FLD LPDDR4__DENALI_PHY_1055__PHY_ADR_CALVL_TRAIN_MASK_0
|
||||
|
||||
#define LPDDR4__DENALI_PHY_1055__PHY_ADR_CSLVL_TRAIN_MASK_0_MASK 0x00003F00U
|
||||
#define LPDDR4__DENALI_PHY_1055__PHY_ADR_CSLVL_TRAIN_MASK_0_SHIFT 8U
|
||||
#define LPDDR4__DENALI_PHY_1055__PHY_ADR_CSLVL_TRAIN_MASK_0_WIDTH 6U
|
||||
#define LPDDR4__PHY_ADR_CSLVL_TRAIN_MASK_0__REG DENALI_PHY_1055
|
||||
#define LPDDR4__PHY_ADR_CSLVL_TRAIN_MASK_0__FLD LPDDR4__DENALI_PHY_1055__PHY_ADR_CSLVL_TRAIN_MASK_0
|
||||
|
||||
#define LPDDR4__DENALI_PHY_1055__PHY_ADR_STATIC_TOG_DISABLE_0_MASK 0x000F0000U
|
||||
#define LPDDR4__DENALI_PHY_1055__PHY_ADR_STATIC_TOG_DISABLE_0_SHIFT 16U
|
||||
#define LPDDR4__DENALI_PHY_1055__PHY_ADR_STATIC_TOG_DISABLE_0_WIDTH 4U
|
||||
#define LPDDR4__PHY_ADR_STATIC_TOG_DISABLE_0__REG DENALI_PHY_1055
|
||||
#define LPDDR4__PHY_ADR_STATIC_TOG_DISABLE_0__FLD LPDDR4__DENALI_PHY_1055__PHY_ADR_STATIC_TOG_DISABLE_0
|
||||
|
||||
#define LPDDR4__DENALI_PHY_1055__PHY_ADR_SW_TXIO_CTRL_0_MASK 0x3F000000U
|
||||
#define LPDDR4__DENALI_PHY_1055__PHY_ADR_SW_TXIO_CTRL_0_SHIFT 24U
|
||||
#define LPDDR4__DENALI_PHY_1055__PHY_ADR_SW_TXIO_CTRL_0_WIDTH 6U
|
||||
#define LPDDR4__PHY_ADR_SW_TXIO_CTRL_0__REG DENALI_PHY_1055
|
||||
#define LPDDR4__PHY_ADR_SW_TXIO_CTRL_0__FLD LPDDR4__DENALI_PHY_1055__PHY_ADR_SW_TXIO_CTRL_0
|
||||
|
||||
#define LPDDR4__DENALI_PHY_1056_READ_MASK 0xFFFFFF03U
|
||||
#define LPDDR4__DENALI_PHY_1056_WRITE_MASK 0xFFFFFF03U
|
||||
#define LPDDR4__DENALI_PHY_1056__PHY_ADR_DC_INIT_DISABLE_0_MASK 0x00000003U
|
||||
#define LPDDR4__DENALI_PHY_1056__PHY_ADR_DC_INIT_DISABLE_0_SHIFT 0U
|
||||
#define LPDDR4__DENALI_PHY_1056__PHY_ADR_DC_INIT_DISABLE_0_WIDTH 2U
|
||||
#define LPDDR4__PHY_ADR_DC_INIT_DISABLE_0__REG DENALI_PHY_1056
|
||||
#define LPDDR4__PHY_ADR_DC_INIT_DISABLE_0__FLD LPDDR4__DENALI_PHY_1056__PHY_ADR_DC_INIT_DISABLE_0
|
||||
|
||||
#define LPDDR4__DENALI_PHY_1056__PHY_ADR_DC_ADR0_CLK_ADJUST_0_MASK 0x0000FF00U
|
||||
#define LPDDR4__DENALI_PHY_1056__PHY_ADR_DC_ADR0_CLK_ADJUST_0_SHIFT 8U
|
||||
#define LPDDR4__DENALI_PHY_1056__PHY_ADR_DC_ADR0_CLK_ADJUST_0_WIDTH 8U
|
||||
#define LPDDR4__PHY_ADR_DC_ADR0_CLK_ADJUST_0__REG DENALI_PHY_1056
|
||||
#define LPDDR4__PHY_ADR_DC_ADR0_CLK_ADJUST_0__FLD LPDDR4__DENALI_PHY_1056__PHY_ADR_DC_ADR0_CLK_ADJUST_0
|
||||
|
||||
#define LPDDR4__DENALI_PHY_1056__PHY_ADR_DC_ADR1_CLK_ADJUST_0_MASK 0x00FF0000U
|
||||
#define LPDDR4__DENALI_PHY_1056__PHY_ADR_DC_ADR1_CLK_ADJUST_0_SHIFT 16U
|
||||
#define LPDDR4__DENALI_PHY_1056__PHY_ADR_DC_ADR1_CLK_ADJUST_0_WIDTH 8U
|
||||
#define LPDDR4__PHY_ADR_DC_ADR1_CLK_ADJUST_0__REG DENALI_PHY_1056
|
||||
#define LPDDR4__PHY_ADR_DC_ADR1_CLK_ADJUST_0__FLD LPDDR4__DENALI_PHY_1056__PHY_ADR_DC_ADR1_CLK_ADJUST_0
|
||||
|
||||
#define LPDDR4__DENALI_PHY_1056__PHY_ADR_DC_ADR2_CLK_ADJUST_0_MASK 0xFF000000U
|
||||
#define LPDDR4__DENALI_PHY_1056__PHY_ADR_DC_ADR2_CLK_ADJUST_0_SHIFT 24U
|
||||
#define LPDDR4__DENALI_PHY_1056__PHY_ADR_DC_ADR2_CLK_ADJUST_0_WIDTH 8U
|
||||
#define LPDDR4__PHY_ADR_DC_ADR2_CLK_ADJUST_0__REG DENALI_PHY_1056
|
||||
#define LPDDR4__PHY_ADR_DC_ADR2_CLK_ADJUST_0__FLD LPDDR4__DENALI_PHY_1056__PHY_ADR_DC_ADR2_CLK_ADJUST_0
|
||||
|
||||
#define LPDDR4__DENALI_PHY_1057_READ_MASK 0x01FFFFFFU
|
||||
#define LPDDR4__DENALI_PHY_1057_WRITE_MASK 0x01FFFFFFU
|
||||
#define LPDDR4__DENALI_PHY_1057__PHY_ADR_DC_ADR3_CLK_ADJUST_0_MASK 0x000000FFU
|
||||
#define LPDDR4__DENALI_PHY_1057__PHY_ADR_DC_ADR3_CLK_ADJUST_0_SHIFT 0U
|
||||
#define LPDDR4__DENALI_PHY_1057__PHY_ADR_DC_ADR3_CLK_ADJUST_0_WIDTH 8U
|
||||
#define LPDDR4__PHY_ADR_DC_ADR3_CLK_ADJUST_0__REG DENALI_PHY_1057
|
||||
#define LPDDR4__PHY_ADR_DC_ADR3_CLK_ADJUST_0__FLD LPDDR4__DENALI_PHY_1057__PHY_ADR_DC_ADR3_CLK_ADJUST_0
|
||||
|
||||
#define LPDDR4__DENALI_PHY_1057__PHY_ADR_DC_ADR4_CLK_ADJUST_0_MASK 0x0000FF00U
|
||||
#define LPDDR4__DENALI_PHY_1057__PHY_ADR_DC_ADR4_CLK_ADJUST_0_SHIFT 8U
|
||||
#define LPDDR4__DENALI_PHY_1057__PHY_ADR_DC_ADR4_CLK_ADJUST_0_WIDTH 8U
|
||||
#define LPDDR4__PHY_ADR_DC_ADR4_CLK_ADJUST_0__REG DENALI_PHY_1057
|
||||
#define LPDDR4__PHY_ADR_DC_ADR4_CLK_ADJUST_0__FLD LPDDR4__DENALI_PHY_1057__PHY_ADR_DC_ADR4_CLK_ADJUST_0
|
||||
|
||||
#define LPDDR4__DENALI_PHY_1057__PHY_ADR_DC_ADR5_CLK_ADJUST_0_MASK 0x00FF0000U
|
||||
#define LPDDR4__DENALI_PHY_1057__PHY_ADR_DC_ADR5_CLK_ADJUST_0_SHIFT 16U
|
||||
#define LPDDR4__DENALI_PHY_1057__PHY_ADR_DC_ADR5_CLK_ADJUST_0_WIDTH 8U
|
||||
#define LPDDR4__PHY_ADR_DC_ADR5_CLK_ADJUST_0__REG DENALI_PHY_1057
|
||||
#define LPDDR4__PHY_ADR_DC_ADR5_CLK_ADJUST_0__FLD LPDDR4__DENALI_PHY_1057__PHY_ADR_DC_ADR5_CLK_ADJUST_0
|
||||
|
||||
#define LPDDR4__DENALI_PHY_1057__PHY_ADR_DCC_RXCAL_CTRL_GATE_DISABLE_0_MASK 0x01000000U
|
||||
#define LPDDR4__DENALI_PHY_1057__PHY_ADR_DCC_RXCAL_CTRL_GATE_DISABLE_0_SHIFT 24U
|
||||
#define LPDDR4__DENALI_PHY_1057__PHY_ADR_DCC_RXCAL_CTRL_GATE_DISABLE_0_WIDTH 1U
|
||||
#define LPDDR4__DENALI_PHY_1057__PHY_ADR_DCC_RXCAL_CTRL_GATE_DISABLE_0_WOCLR 0U
|
||||
#define LPDDR4__DENALI_PHY_1057__PHY_ADR_DCC_RXCAL_CTRL_GATE_DISABLE_0_WOSET 0U
|
||||
#define LPDDR4__PHY_ADR_DCC_RXCAL_CTRL_GATE_DISABLE_0__REG DENALI_PHY_1057
|
||||
#define LPDDR4__PHY_ADR_DCC_RXCAL_CTRL_GATE_DISABLE_0__FLD LPDDR4__DENALI_PHY_1057__PHY_ADR_DCC_RXCAL_CTRL_GATE_DISABLE_0
|
||||
|
||||
#define LPDDR4__DENALI_PHY_1058_READ_MASK 0x3F03FFFFU
|
||||
#define LPDDR4__DENALI_PHY_1058_WRITE_MASK 0x3F03FFFFU
|
||||
#define LPDDR4__DENALI_PHY_1058__PHY_ADR_DC_CAL_SAMPLE_WAIT_0_MASK 0x000000FFU
|
||||
#define LPDDR4__DENALI_PHY_1058__PHY_ADR_DC_CAL_SAMPLE_WAIT_0_SHIFT 0U
|
||||
#define LPDDR4__DENALI_PHY_1058__PHY_ADR_DC_CAL_SAMPLE_WAIT_0_WIDTH 8U
|
||||
#define LPDDR4__PHY_ADR_DC_CAL_SAMPLE_WAIT_0__REG DENALI_PHY_1058
|
||||
#define LPDDR4__PHY_ADR_DC_CAL_SAMPLE_WAIT_0__FLD LPDDR4__DENALI_PHY_1058__PHY_ADR_DC_CAL_SAMPLE_WAIT_0
|
||||
|
||||
#define LPDDR4__DENALI_PHY_1058__PHY_ADR_DC_CAL_TIMEOUT_0_MASK 0x0000FF00U
|
||||
#define LPDDR4__DENALI_PHY_1058__PHY_ADR_DC_CAL_TIMEOUT_0_SHIFT 8U
|
||||
#define LPDDR4__DENALI_PHY_1058__PHY_ADR_DC_CAL_TIMEOUT_0_WIDTH 8U
|
||||
#define LPDDR4__PHY_ADR_DC_CAL_TIMEOUT_0__REG DENALI_PHY_1058
|
||||
#define LPDDR4__PHY_ADR_DC_CAL_TIMEOUT_0__FLD LPDDR4__DENALI_PHY_1058__PHY_ADR_DC_CAL_TIMEOUT_0
|
||||
|
||||
#define LPDDR4__DENALI_PHY_1058__PHY_ADR_DC_WEIGHT_0_MASK 0x00030000U
|
||||
#define LPDDR4__DENALI_PHY_1058__PHY_ADR_DC_WEIGHT_0_SHIFT 16U
|
||||
#define LPDDR4__DENALI_PHY_1058__PHY_ADR_DC_WEIGHT_0_WIDTH 2U
|
||||
#define LPDDR4__PHY_ADR_DC_WEIGHT_0__REG DENALI_PHY_1058
|
||||
#define LPDDR4__PHY_ADR_DC_WEIGHT_0__FLD LPDDR4__DENALI_PHY_1058__PHY_ADR_DC_WEIGHT_0
|
||||
|
||||
#define LPDDR4__DENALI_PHY_1058__PHY_ADR_DC_ADJUST_START_0_MASK 0x3F000000U
|
||||
#define LPDDR4__DENALI_PHY_1058__PHY_ADR_DC_ADJUST_START_0_SHIFT 24U
|
||||
#define LPDDR4__DENALI_PHY_1058__PHY_ADR_DC_ADJUST_START_0_WIDTH 6U
|
||||
#define LPDDR4__PHY_ADR_DC_ADJUST_START_0__REG DENALI_PHY_1058
|
||||
#define LPDDR4__PHY_ADR_DC_ADJUST_START_0__FLD LPDDR4__DENALI_PHY_1058__PHY_ADR_DC_ADJUST_START_0
|
||||
|
||||
#define LPDDR4__DENALI_PHY_1059_READ_MASK 0x0101FFFFU
|
||||
#define LPDDR4__DENALI_PHY_1059_WRITE_MASK 0x0101FFFFU
|
||||
#define LPDDR4__DENALI_PHY_1059__PHY_ADR_DC_ADJUST_SAMPLE_CNT_0_MASK 0x000000FFU
|
||||
#define LPDDR4__DENALI_PHY_1059__PHY_ADR_DC_ADJUST_SAMPLE_CNT_0_SHIFT 0U
|
||||
#define LPDDR4__DENALI_PHY_1059__PHY_ADR_DC_ADJUST_SAMPLE_CNT_0_WIDTH 8U
|
||||
#define LPDDR4__PHY_ADR_DC_ADJUST_SAMPLE_CNT_0__REG DENALI_PHY_1059
|
||||
#define LPDDR4__PHY_ADR_DC_ADJUST_SAMPLE_CNT_0__FLD LPDDR4__DENALI_PHY_1059__PHY_ADR_DC_ADJUST_SAMPLE_CNT_0
|
||||
|
||||
#define LPDDR4__DENALI_PHY_1059__PHY_ADR_DC_ADJUST_THRSHLD_0_MASK 0x0000FF00U
|
||||
#define LPDDR4__DENALI_PHY_1059__PHY_ADR_DC_ADJUST_THRSHLD_0_SHIFT 8U
|
||||
#define LPDDR4__DENALI_PHY_1059__PHY_ADR_DC_ADJUST_THRSHLD_0_WIDTH 8U
|
||||
#define LPDDR4__PHY_ADR_DC_ADJUST_THRSHLD_0__REG DENALI_PHY_1059
|
||||
#define LPDDR4__PHY_ADR_DC_ADJUST_THRSHLD_0__FLD LPDDR4__DENALI_PHY_1059__PHY_ADR_DC_ADJUST_THRSHLD_0
|
||||
|
||||
#define LPDDR4__DENALI_PHY_1059__PHY_ADR_DC_ADJUST_DIRECT_0_MASK 0x00010000U
|
||||
#define LPDDR4__DENALI_PHY_1059__PHY_ADR_DC_ADJUST_DIRECT_0_SHIFT 16U
|
||||
#define LPDDR4__DENALI_PHY_1059__PHY_ADR_DC_ADJUST_DIRECT_0_WIDTH 1U
|
||||
#define LPDDR4__DENALI_PHY_1059__PHY_ADR_DC_ADJUST_DIRECT_0_WOCLR 0U
|
||||
#define LPDDR4__DENALI_PHY_1059__PHY_ADR_DC_ADJUST_DIRECT_0_WOSET 0U
|
||||
#define LPDDR4__PHY_ADR_DC_ADJUST_DIRECT_0__REG DENALI_PHY_1059
|
||||
#define LPDDR4__PHY_ADR_DC_ADJUST_DIRECT_0__FLD LPDDR4__DENALI_PHY_1059__PHY_ADR_DC_ADJUST_DIRECT_0
|
||||
|
||||
#define LPDDR4__DENALI_PHY_1059__PHY_ADR_DC_CAL_POLARITY_0_MASK 0x01000000U
|
||||
#define LPDDR4__DENALI_PHY_1059__PHY_ADR_DC_CAL_POLARITY_0_SHIFT 24U
|
||||
#define LPDDR4__DENALI_PHY_1059__PHY_ADR_DC_CAL_POLARITY_0_WIDTH 1U
|
||||
#define LPDDR4__DENALI_PHY_1059__PHY_ADR_DC_CAL_POLARITY_0_WOCLR 0U
|
||||
#define LPDDR4__DENALI_PHY_1059__PHY_ADR_DC_CAL_POLARITY_0_WOSET 0U
|
||||
#define LPDDR4__PHY_ADR_DC_CAL_POLARITY_0__REG DENALI_PHY_1059
|
||||
#define LPDDR4__PHY_ADR_DC_CAL_POLARITY_0__FLD LPDDR4__DENALI_PHY_1059__PHY_ADR_DC_CAL_POLARITY_0
|
||||
|
||||
#define LPDDR4__DENALI_PHY_1060_READ_MASK 0x07FF3F01U
|
||||
#define LPDDR4__DENALI_PHY_1060_WRITE_MASK 0x07FF3F01U
|
||||
#define LPDDR4__DENALI_PHY_1060__PHY_ADR_DC_CAL_START_0_MASK 0x00000001U
|
||||
#define LPDDR4__DENALI_PHY_1060__PHY_ADR_DC_CAL_START_0_SHIFT 0U
|
||||
#define LPDDR4__DENALI_PHY_1060__PHY_ADR_DC_CAL_START_0_WIDTH 1U
|
||||
#define LPDDR4__DENALI_PHY_1060__PHY_ADR_DC_CAL_START_0_WOCLR 0U
|
||||
#define LPDDR4__DENALI_PHY_1060__PHY_ADR_DC_CAL_START_0_WOSET 0U
|
||||
#define LPDDR4__PHY_ADR_DC_CAL_START_0__REG DENALI_PHY_1060
|
||||
#define LPDDR4__PHY_ADR_DC_CAL_START_0__FLD LPDDR4__DENALI_PHY_1060__PHY_ADR_DC_CAL_START_0
|
||||
|
||||
#define LPDDR4__DENALI_PHY_1060__PHY_ADR_SW_TXPWR_CTRL_0_MASK 0x00003F00U
|
||||
#define LPDDR4__DENALI_PHY_1060__PHY_ADR_SW_TXPWR_CTRL_0_SHIFT 8U
|
||||
#define LPDDR4__DENALI_PHY_1060__PHY_ADR_SW_TXPWR_CTRL_0_WIDTH 6U
|
||||
#define LPDDR4__PHY_ADR_SW_TXPWR_CTRL_0__REG DENALI_PHY_1060
|
||||
#define LPDDR4__PHY_ADR_SW_TXPWR_CTRL_0__FLD LPDDR4__DENALI_PHY_1060__PHY_ADR_SW_TXPWR_CTRL_0
|
||||
|
||||
#define LPDDR4__DENALI_PHY_1060__PHY_PARITY_ERROR_REGIF_ADR_0_MASK 0x07FF0000U
|
||||
#define LPDDR4__DENALI_PHY_1060__PHY_PARITY_ERROR_REGIF_ADR_0_SHIFT 16U
|
||||
#define LPDDR4__DENALI_PHY_1060__PHY_PARITY_ERROR_REGIF_ADR_0_WIDTH 11U
|
||||
#define LPDDR4__PHY_PARITY_ERROR_REGIF_ADR_0__REG DENALI_PHY_1060
|
||||
#define LPDDR4__PHY_PARITY_ERROR_REGIF_ADR_0__FLD LPDDR4__DENALI_PHY_1060__PHY_PARITY_ERROR_REGIF_ADR_0
|
||||
|
||||
#define LPDDR4__DENALI_PHY_1061_READ_MASK 0x01FF01FFU
|
||||
#define LPDDR4__DENALI_PHY_1061_WRITE_MASK 0x01FF01FFU
|
||||
#define LPDDR4__DENALI_PHY_1061__PHY_AS_FSM_ERROR_INFO_0_MASK 0x000001FFU
|
||||
#define LPDDR4__DENALI_PHY_1061__PHY_AS_FSM_ERROR_INFO_0_SHIFT 0U
|
||||
#define LPDDR4__DENALI_PHY_1061__PHY_AS_FSM_ERROR_INFO_0_WIDTH 9U
|
||||
#define LPDDR4__PHY_AS_FSM_ERROR_INFO_0__REG DENALI_PHY_1061
|
||||
#define LPDDR4__PHY_AS_FSM_ERROR_INFO_0__FLD LPDDR4__DENALI_PHY_1061__PHY_AS_FSM_ERROR_INFO_0
|
||||
|
||||
#define LPDDR4__DENALI_PHY_1061__PHY_AS_FSM_ERROR_INFO_MASK_0_MASK 0x01FF0000U
|
||||
#define LPDDR4__DENALI_PHY_1061__PHY_AS_FSM_ERROR_INFO_MASK_0_SHIFT 16U
|
||||
#define LPDDR4__DENALI_PHY_1061__PHY_AS_FSM_ERROR_INFO_MASK_0_WIDTH 9U
|
||||
#define LPDDR4__PHY_AS_FSM_ERROR_INFO_MASK_0__REG DENALI_PHY_1061
|
||||
#define LPDDR4__PHY_AS_FSM_ERROR_INFO_MASK_0__FLD LPDDR4__DENALI_PHY_1061__PHY_AS_FSM_ERROR_INFO_MASK_0
|
||||
|
||||
#define LPDDR4__DENALI_PHY_1062_READ_MASK 0x01010000U
|
||||
#define LPDDR4__DENALI_PHY_1062_WRITE_MASK 0x01010000U
|
||||
#define LPDDR4__DENALI_PHY_1062__SC_PHY_AS_FSM_ERROR_INFO_WOCLR_0_MASK 0x000001FFU
|
||||
#define LPDDR4__DENALI_PHY_1062__SC_PHY_AS_FSM_ERROR_INFO_WOCLR_0_SHIFT 0U
|
||||
#define LPDDR4__DENALI_PHY_1062__SC_PHY_AS_FSM_ERROR_INFO_WOCLR_0_WIDTH 9U
|
||||
#define LPDDR4__SC_PHY_AS_FSM_ERROR_INFO_WOCLR_0__REG DENALI_PHY_1062
|
||||
#define LPDDR4__SC_PHY_AS_FSM_ERROR_INFO_WOCLR_0__FLD LPDDR4__DENALI_PHY_1062__SC_PHY_AS_FSM_ERROR_INFO_WOCLR_0
|
||||
|
||||
#define LPDDR4__DENALI_PHY_1062__PHY_AS_TRAIN_CALIB_ERROR_INFO_0_MASK 0x00010000U
|
||||
#define LPDDR4__DENALI_PHY_1062__PHY_AS_TRAIN_CALIB_ERROR_INFO_0_SHIFT 16U
|
||||
#define LPDDR4__DENALI_PHY_1062__PHY_AS_TRAIN_CALIB_ERROR_INFO_0_WIDTH 1U
|
||||
#define LPDDR4__DENALI_PHY_1062__PHY_AS_TRAIN_CALIB_ERROR_INFO_0_WOCLR 0U
|
||||
#define LPDDR4__DENALI_PHY_1062__PHY_AS_TRAIN_CALIB_ERROR_INFO_0_WOSET 0U
|
||||
#define LPDDR4__PHY_AS_TRAIN_CALIB_ERROR_INFO_0__REG DENALI_PHY_1062
|
||||
#define LPDDR4__PHY_AS_TRAIN_CALIB_ERROR_INFO_0__FLD LPDDR4__DENALI_PHY_1062__PHY_AS_TRAIN_CALIB_ERROR_INFO_0
|
||||
|
||||
#define LPDDR4__DENALI_PHY_1062__PHY_AS_TRAIN_CALIB_ERROR_INFO_MASK_0_MASK 0x01000000U
|
||||
#define LPDDR4__DENALI_PHY_1062__PHY_AS_TRAIN_CALIB_ERROR_INFO_MASK_0_SHIFT 24U
|
||||
#define LPDDR4__DENALI_PHY_1062__PHY_AS_TRAIN_CALIB_ERROR_INFO_MASK_0_WIDTH 1U
|
||||
#define LPDDR4__DENALI_PHY_1062__PHY_AS_TRAIN_CALIB_ERROR_INFO_MASK_0_WOCLR 0U
|
||||
#define LPDDR4__DENALI_PHY_1062__PHY_AS_TRAIN_CALIB_ERROR_INFO_MASK_0_WOSET 0U
|
||||
#define LPDDR4__PHY_AS_TRAIN_CALIB_ERROR_INFO_MASK_0__REG DENALI_PHY_1062
|
||||
#define LPDDR4__PHY_AS_TRAIN_CALIB_ERROR_INFO_MASK_0__FLD LPDDR4__DENALI_PHY_1062__PHY_AS_TRAIN_CALIB_ERROR_INFO_MASK_0
|
||||
|
||||
#define LPDDR4__DENALI_PHY_1063__SC_PHY_AS_TRAIN_CALIB_ERROR_INFO_WOCLR_0_MASK 0x00000001U
|
||||
#define LPDDR4__DENALI_PHY_1063__SC_PHY_AS_TRAIN_CALIB_ERROR_INFO_WOCLR_0_SHIFT 0U
|
||||
#define LPDDR4__DENALI_PHY_1063__SC_PHY_AS_TRAIN_CALIB_ERROR_INFO_WOCLR_0_WIDTH 1U
|
||||
#define LPDDR4__DENALI_PHY_1063__SC_PHY_AS_TRAIN_CALIB_ERROR_INFO_WOCLR_0_WOCLR 0U
|
||||
#define LPDDR4__DENALI_PHY_1063__SC_PHY_AS_TRAIN_CALIB_ERROR_INFO_WOCLR_0_WOSET 0U
|
||||
#define LPDDR4__SC_PHY_AS_TRAIN_CALIB_ERROR_INFO_WOCLR_0__REG DENALI_PHY_1063
|
||||
#define LPDDR4__SC_PHY_AS_TRAIN_CALIB_ERROR_INFO_WOCLR_0__FLD LPDDR4__DENALI_PHY_1063__SC_PHY_AS_TRAIN_CALIB_ERROR_INFO_WOCLR_0
|
||||
|
||||
#define LPDDR4__DENALI_PHY_1064_READ_MASK 0x07FF07FFU
|
||||
#define LPDDR4__DENALI_PHY_1064_WRITE_MASK 0x07FF07FFU
|
||||
#define LPDDR4__DENALI_PHY_1064__PHY_ADR_TSEL_SELECT_0_MASK 0x000000FFU
|
||||
#define LPDDR4__DENALI_PHY_1064__PHY_ADR_TSEL_SELECT_0_SHIFT 0U
|
||||
#define LPDDR4__DENALI_PHY_1064__PHY_ADR_TSEL_SELECT_0_WIDTH 8U
|
||||
#define LPDDR4__PHY_ADR_TSEL_SELECT_0__REG DENALI_PHY_1064
|
||||
#define LPDDR4__PHY_ADR_TSEL_SELECT_0__FLD LPDDR4__DENALI_PHY_1064__PHY_ADR_TSEL_SELECT_0
|
||||
|
||||
#define LPDDR4__DENALI_PHY_1064__PHY_ADR_DC_CAL_CLK_SEL_0_MASK 0x00000700U
|
||||
#define LPDDR4__DENALI_PHY_1064__PHY_ADR_DC_CAL_CLK_SEL_0_SHIFT 8U
|
||||
#define LPDDR4__DENALI_PHY_1064__PHY_ADR_DC_CAL_CLK_SEL_0_WIDTH 3U
|
||||
#define LPDDR4__PHY_ADR_DC_CAL_CLK_SEL_0__REG DENALI_PHY_1064
|
||||
#define LPDDR4__PHY_ADR_DC_CAL_CLK_SEL_0__FLD LPDDR4__DENALI_PHY_1064__PHY_ADR_DC_CAL_CLK_SEL_0
|
||||
|
||||
#define LPDDR4__DENALI_PHY_1064__PHY_PAD_ADR_IO_CFG_0_MASK 0x07FF0000U
|
||||
#define LPDDR4__DENALI_PHY_1064__PHY_PAD_ADR_IO_CFG_0_SHIFT 16U
|
||||
#define LPDDR4__DENALI_PHY_1064__PHY_PAD_ADR_IO_CFG_0_WIDTH 11U
|
||||
#define LPDDR4__PHY_PAD_ADR_IO_CFG_0__REG DENALI_PHY_1064
|
||||
#define LPDDR4__PHY_PAD_ADR_IO_CFG_0__FLD LPDDR4__DENALI_PHY_1064__PHY_PAD_ADR_IO_CFG_0
|
||||
|
||||
#define LPDDR4__DENALI_PHY_1065_READ_MASK 0x1F07FF1FU
|
||||
#define LPDDR4__DENALI_PHY_1065_WRITE_MASK 0x1F07FF1FU
|
||||
#define LPDDR4__DENALI_PHY_1065__PHY_ADR0_SW_WRADDR_SHIFT_0_MASK 0x0000001FU
|
||||
#define LPDDR4__DENALI_PHY_1065__PHY_ADR0_SW_WRADDR_SHIFT_0_SHIFT 0U
|
||||
#define LPDDR4__DENALI_PHY_1065__PHY_ADR0_SW_WRADDR_SHIFT_0_WIDTH 5U
|
||||
#define LPDDR4__PHY_ADR0_SW_WRADDR_SHIFT_0__REG DENALI_PHY_1065
|
||||
#define LPDDR4__PHY_ADR0_SW_WRADDR_SHIFT_0__FLD LPDDR4__DENALI_PHY_1065__PHY_ADR0_SW_WRADDR_SHIFT_0
|
||||
|
||||
#define LPDDR4__DENALI_PHY_1065__PHY_ADR0_CLK_WR_SLAVE_DELAY_0_MASK 0x0007FF00U
|
||||
#define LPDDR4__DENALI_PHY_1065__PHY_ADR0_CLK_WR_SLAVE_DELAY_0_SHIFT 8U
|
||||
#define LPDDR4__DENALI_PHY_1065__PHY_ADR0_CLK_WR_SLAVE_DELAY_0_WIDTH 11U
|
||||
#define LPDDR4__PHY_ADR0_CLK_WR_SLAVE_DELAY_0__REG DENALI_PHY_1065
|
||||
#define LPDDR4__PHY_ADR0_CLK_WR_SLAVE_DELAY_0__FLD LPDDR4__DENALI_PHY_1065__PHY_ADR0_CLK_WR_SLAVE_DELAY_0
|
||||
|
||||
#define LPDDR4__DENALI_PHY_1065__PHY_ADR1_SW_WRADDR_SHIFT_0_MASK 0x1F000000U
|
||||
#define LPDDR4__DENALI_PHY_1065__PHY_ADR1_SW_WRADDR_SHIFT_0_SHIFT 24U
|
||||
#define LPDDR4__DENALI_PHY_1065__PHY_ADR1_SW_WRADDR_SHIFT_0_WIDTH 5U
|
||||
#define LPDDR4__PHY_ADR1_SW_WRADDR_SHIFT_0__REG DENALI_PHY_1065
|
||||
#define LPDDR4__PHY_ADR1_SW_WRADDR_SHIFT_0__FLD LPDDR4__DENALI_PHY_1065__PHY_ADR1_SW_WRADDR_SHIFT_0
|
||||
|
||||
#define LPDDR4__DENALI_PHY_1066_READ_MASK 0x001F07FFU
|
||||
#define LPDDR4__DENALI_PHY_1066_WRITE_MASK 0x001F07FFU
|
||||
#define LPDDR4__DENALI_PHY_1066__PHY_ADR1_CLK_WR_SLAVE_DELAY_0_MASK 0x000007FFU
|
||||
#define LPDDR4__DENALI_PHY_1066__PHY_ADR1_CLK_WR_SLAVE_DELAY_0_SHIFT 0U
|
||||
#define LPDDR4__DENALI_PHY_1066__PHY_ADR1_CLK_WR_SLAVE_DELAY_0_WIDTH 11U
|
||||
#define LPDDR4__PHY_ADR1_CLK_WR_SLAVE_DELAY_0__REG DENALI_PHY_1066
|
||||
#define LPDDR4__PHY_ADR1_CLK_WR_SLAVE_DELAY_0__FLD LPDDR4__DENALI_PHY_1066__PHY_ADR1_CLK_WR_SLAVE_DELAY_0
|
||||
|
||||
#define LPDDR4__DENALI_PHY_1066__PHY_ADR2_SW_WRADDR_SHIFT_0_MASK 0x001F0000U
|
||||
#define LPDDR4__DENALI_PHY_1066__PHY_ADR2_SW_WRADDR_SHIFT_0_SHIFT 16U
|
||||
#define LPDDR4__DENALI_PHY_1066__PHY_ADR2_SW_WRADDR_SHIFT_0_WIDTH 5U
|
||||
#define LPDDR4__PHY_ADR2_SW_WRADDR_SHIFT_0__REG DENALI_PHY_1066
|
||||
#define LPDDR4__PHY_ADR2_SW_WRADDR_SHIFT_0__FLD LPDDR4__DENALI_PHY_1066__PHY_ADR2_SW_WRADDR_SHIFT_0
|
||||
|
||||
#define LPDDR4__DENALI_PHY_1067_READ_MASK 0x001F07FFU
|
||||
#define LPDDR4__DENALI_PHY_1067_WRITE_MASK 0x001F07FFU
|
||||
#define LPDDR4__DENALI_PHY_1067__PHY_ADR2_CLK_WR_SLAVE_DELAY_0_MASK 0x000007FFU
|
||||
#define LPDDR4__DENALI_PHY_1067__PHY_ADR2_CLK_WR_SLAVE_DELAY_0_SHIFT 0U
|
||||
#define LPDDR4__DENALI_PHY_1067__PHY_ADR2_CLK_WR_SLAVE_DELAY_0_WIDTH 11U
|
||||
#define LPDDR4__PHY_ADR2_CLK_WR_SLAVE_DELAY_0__REG DENALI_PHY_1067
|
||||
#define LPDDR4__PHY_ADR2_CLK_WR_SLAVE_DELAY_0__FLD LPDDR4__DENALI_PHY_1067__PHY_ADR2_CLK_WR_SLAVE_DELAY_0
|
||||
|
||||
#define LPDDR4__DENALI_PHY_1067__PHY_ADR3_SW_WRADDR_SHIFT_0_MASK 0x001F0000U
|
||||
#define LPDDR4__DENALI_PHY_1067__PHY_ADR3_SW_WRADDR_SHIFT_0_SHIFT 16U
|
||||
#define LPDDR4__DENALI_PHY_1067__PHY_ADR3_SW_WRADDR_SHIFT_0_WIDTH 5U
|
||||
#define LPDDR4__PHY_ADR3_SW_WRADDR_SHIFT_0__REG DENALI_PHY_1067
|
||||
#define LPDDR4__PHY_ADR3_SW_WRADDR_SHIFT_0__FLD LPDDR4__DENALI_PHY_1067__PHY_ADR3_SW_WRADDR_SHIFT_0
|
||||
|
||||
#define LPDDR4__DENALI_PHY_1068_READ_MASK 0x001F07FFU
|
||||
#define LPDDR4__DENALI_PHY_1068_WRITE_MASK 0x001F07FFU
|
||||
#define LPDDR4__DENALI_PHY_1068__PHY_ADR3_CLK_WR_SLAVE_DELAY_0_MASK 0x000007FFU
|
||||
#define LPDDR4__DENALI_PHY_1068__PHY_ADR3_CLK_WR_SLAVE_DELAY_0_SHIFT 0U
|
||||
#define LPDDR4__DENALI_PHY_1068__PHY_ADR3_CLK_WR_SLAVE_DELAY_0_WIDTH 11U
|
||||
#define LPDDR4__PHY_ADR3_CLK_WR_SLAVE_DELAY_0__REG DENALI_PHY_1068
|
||||
#define LPDDR4__PHY_ADR3_CLK_WR_SLAVE_DELAY_0__FLD LPDDR4__DENALI_PHY_1068__PHY_ADR3_CLK_WR_SLAVE_DELAY_0
|
||||
|
||||
#define LPDDR4__DENALI_PHY_1068__PHY_ADR4_SW_WRADDR_SHIFT_0_MASK 0x001F0000U
|
||||
#define LPDDR4__DENALI_PHY_1068__PHY_ADR4_SW_WRADDR_SHIFT_0_SHIFT 16U
|
||||
#define LPDDR4__DENALI_PHY_1068__PHY_ADR4_SW_WRADDR_SHIFT_0_WIDTH 5U
|
||||
#define LPDDR4__PHY_ADR4_SW_WRADDR_SHIFT_0__REG DENALI_PHY_1068
|
||||
#define LPDDR4__PHY_ADR4_SW_WRADDR_SHIFT_0__FLD LPDDR4__DENALI_PHY_1068__PHY_ADR4_SW_WRADDR_SHIFT_0
|
||||
|
||||
#define LPDDR4__DENALI_PHY_1069_READ_MASK 0x001F07FFU
|
||||
#define LPDDR4__DENALI_PHY_1069_WRITE_MASK 0x001F07FFU
|
||||
#define LPDDR4__DENALI_PHY_1069__PHY_ADR4_CLK_WR_SLAVE_DELAY_0_MASK 0x000007FFU
|
||||
#define LPDDR4__DENALI_PHY_1069__PHY_ADR4_CLK_WR_SLAVE_DELAY_0_SHIFT 0U
|
||||
#define LPDDR4__DENALI_PHY_1069__PHY_ADR4_CLK_WR_SLAVE_DELAY_0_WIDTH 11U
|
||||
#define LPDDR4__PHY_ADR4_CLK_WR_SLAVE_DELAY_0__REG DENALI_PHY_1069
|
||||
#define LPDDR4__PHY_ADR4_CLK_WR_SLAVE_DELAY_0__FLD LPDDR4__DENALI_PHY_1069__PHY_ADR4_CLK_WR_SLAVE_DELAY_0
|
||||
|
||||
#define LPDDR4__DENALI_PHY_1069__PHY_ADR5_SW_WRADDR_SHIFT_0_MASK 0x001F0000U
|
||||
#define LPDDR4__DENALI_PHY_1069__PHY_ADR5_SW_WRADDR_SHIFT_0_SHIFT 16U
|
||||
#define LPDDR4__DENALI_PHY_1069__PHY_ADR5_SW_WRADDR_SHIFT_0_WIDTH 5U
|
||||
#define LPDDR4__PHY_ADR5_SW_WRADDR_SHIFT_0__REG DENALI_PHY_1069
|
||||
#define LPDDR4__PHY_ADR5_SW_WRADDR_SHIFT_0__FLD LPDDR4__DENALI_PHY_1069__PHY_ADR5_SW_WRADDR_SHIFT_0
|
||||
|
||||
#define LPDDR4__DENALI_PHY_1070_READ_MASK 0x000F07FFU
|
||||
#define LPDDR4__DENALI_PHY_1070_WRITE_MASK 0x000F07FFU
|
||||
#define LPDDR4__DENALI_PHY_1070__PHY_ADR5_CLK_WR_SLAVE_DELAY_0_MASK 0x000007FFU
|
||||
#define LPDDR4__DENALI_PHY_1070__PHY_ADR5_CLK_WR_SLAVE_DELAY_0_SHIFT 0U
|
||||
#define LPDDR4__DENALI_PHY_1070__PHY_ADR5_CLK_WR_SLAVE_DELAY_0_WIDTH 11U
|
||||
#define LPDDR4__PHY_ADR5_CLK_WR_SLAVE_DELAY_0__REG DENALI_PHY_1070
|
||||
#define LPDDR4__PHY_ADR5_CLK_WR_SLAVE_DELAY_0__FLD LPDDR4__DENALI_PHY_1070__PHY_ADR5_CLK_WR_SLAVE_DELAY_0
|
||||
|
||||
#define LPDDR4__DENALI_PHY_1070__PHY_ADR_SW_MASTER_MODE_0_MASK 0x000F0000U
|
||||
#define LPDDR4__DENALI_PHY_1070__PHY_ADR_SW_MASTER_MODE_0_SHIFT 16U
|
||||
#define LPDDR4__DENALI_PHY_1070__PHY_ADR_SW_MASTER_MODE_0_WIDTH 4U
|
||||
#define LPDDR4__PHY_ADR_SW_MASTER_MODE_0__REG DENALI_PHY_1070
|
||||
#define LPDDR4__PHY_ADR_SW_MASTER_MODE_0__FLD LPDDR4__DENALI_PHY_1070__PHY_ADR_SW_MASTER_MODE_0
|
||||
|
||||
#define LPDDR4__DENALI_PHY_1071_READ_MASK 0xFF3F07FFU
|
||||
#define LPDDR4__DENALI_PHY_1071_WRITE_MASK 0xFF3F07FFU
|
||||
#define LPDDR4__DENALI_PHY_1071__PHY_ADR_MASTER_DELAY_START_0_MASK 0x000007FFU
|
||||
#define LPDDR4__DENALI_PHY_1071__PHY_ADR_MASTER_DELAY_START_0_SHIFT 0U
|
||||
#define LPDDR4__DENALI_PHY_1071__PHY_ADR_MASTER_DELAY_START_0_WIDTH 11U
|
||||
#define LPDDR4__PHY_ADR_MASTER_DELAY_START_0__REG DENALI_PHY_1071
|
||||
#define LPDDR4__PHY_ADR_MASTER_DELAY_START_0__FLD LPDDR4__DENALI_PHY_1071__PHY_ADR_MASTER_DELAY_START_0
|
||||
|
||||
#define LPDDR4__DENALI_PHY_1071__PHY_ADR_MASTER_DELAY_STEP_0_MASK 0x003F0000U
|
||||
#define LPDDR4__DENALI_PHY_1071__PHY_ADR_MASTER_DELAY_STEP_0_SHIFT 16U
|
||||
#define LPDDR4__DENALI_PHY_1071__PHY_ADR_MASTER_DELAY_STEP_0_WIDTH 6U
|
||||
#define LPDDR4__PHY_ADR_MASTER_DELAY_STEP_0__REG DENALI_PHY_1071
|
||||
#define LPDDR4__PHY_ADR_MASTER_DELAY_STEP_0__FLD LPDDR4__DENALI_PHY_1071__PHY_ADR_MASTER_DELAY_STEP_0
|
||||
|
||||
#define LPDDR4__DENALI_PHY_1071__PHY_ADR_MASTER_DELAY_WAIT_0_MASK 0xFF000000U
|
||||
#define LPDDR4__DENALI_PHY_1071__PHY_ADR_MASTER_DELAY_WAIT_0_SHIFT 24U
|
||||
#define LPDDR4__DENALI_PHY_1071__PHY_ADR_MASTER_DELAY_WAIT_0_WIDTH 8U
|
||||
#define LPDDR4__PHY_ADR_MASTER_DELAY_WAIT_0__REG DENALI_PHY_1071
|
||||
#define LPDDR4__PHY_ADR_MASTER_DELAY_WAIT_0__FLD LPDDR4__DENALI_PHY_1071__PHY_ADR_MASTER_DELAY_WAIT_0
|
||||
|
||||
#define LPDDR4__DENALI_PHY_1072_READ_MASK 0x0103FFFFU
|
||||
#define LPDDR4__DENALI_PHY_1072_WRITE_MASK 0x0103FFFFU
|
||||
#define LPDDR4__DENALI_PHY_1072__PHY_ADR_MASTER_DELAY_HALF_MEASURE_0_MASK 0x000000FFU
|
||||
#define LPDDR4__DENALI_PHY_1072__PHY_ADR_MASTER_DELAY_HALF_MEASURE_0_SHIFT 0U
|
||||
#define LPDDR4__DENALI_PHY_1072__PHY_ADR_MASTER_DELAY_HALF_MEASURE_0_WIDTH 8U
|
||||
#define LPDDR4__PHY_ADR_MASTER_DELAY_HALF_MEASURE_0__REG DENALI_PHY_1072
|
||||
#define LPDDR4__PHY_ADR_MASTER_DELAY_HALF_MEASURE_0__FLD LPDDR4__DENALI_PHY_1072__PHY_ADR_MASTER_DELAY_HALF_MEASURE_0
|
||||
|
||||
#define LPDDR4__DENALI_PHY_1072__PHY_ADR_SW_CALVL_DVW_MIN_0_MASK 0x0003FF00U
|
||||
#define LPDDR4__DENALI_PHY_1072__PHY_ADR_SW_CALVL_DVW_MIN_0_SHIFT 8U
|
||||
#define LPDDR4__DENALI_PHY_1072__PHY_ADR_SW_CALVL_DVW_MIN_0_WIDTH 10U
|
||||
#define LPDDR4__PHY_ADR_SW_CALVL_DVW_MIN_0__REG DENALI_PHY_1072
|
||||
#define LPDDR4__PHY_ADR_SW_CALVL_DVW_MIN_0__FLD LPDDR4__DENALI_PHY_1072__PHY_ADR_SW_CALVL_DVW_MIN_0
|
||||
|
||||
#define LPDDR4__DENALI_PHY_1072__PHY_ADR_SW_CALVL_DVW_MIN_EN_0_MASK 0x01000000U
|
||||
#define LPDDR4__DENALI_PHY_1072__PHY_ADR_SW_CALVL_DVW_MIN_EN_0_SHIFT 24U
|
||||
#define LPDDR4__DENALI_PHY_1072__PHY_ADR_SW_CALVL_DVW_MIN_EN_0_WIDTH 1U
|
||||
#define LPDDR4__DENALI_PHY_1072__PHY_ADR_SW_CALVL_DVW_MIN_EN_0_WOCLR 0U
|
||||
#define LPDDR4__DENALI_PHY_1072__PHY_ADR_SW_CALVL_DVW_MIN_EN_0_WOSET 0U
|
||||
#define LPDDR4__PHY_ADR_SW_CALVL_DVW_MIN_EN_0__REG DENALI_PHY_1072
|
||||
#define LPDDR4__PHY_ADR_SW_CALVL_DVW_MIN_EN_0__FLD LPDDR4__DENALI_PHY_1072__PHY_ADR_SW_CALVL_DVW_MIN_EN_0
|
||||
|
||||
#define LPDDR4__DENALI_PHY_1073_READ_MASK 0x0000000FU
|
||||
#define LPDDR4__DENALI_PHY_1073_WRITE_MASK 0x0000000FU
|
||||
#define LPDDR4__DENALI_PHY_1073__PHY_ADR_CALVL_DLY_STEP_0_MASK 0x0000000FU
|
||||
#define LPDDR4__DENALI_PHY_1073__PHY_ADR_CALVL_DLY_STEP_0_SHIFT 0U
|
||||
#define LPDDR4__DENALI_PHY_1073__PHY_ADR_CALVL_DLY_STEP_0_WIDTH 4U
|
||||
#define LPDDR4__PHY_ADR_CALVL_DLY_STEP_0__REG DENALI_PHY_1073
|
||||
#define LPDDR4__PHY_ADR_CALVL_DLY_STEP_0__FLD LPDDR4__DENALI_PHY_1073__PHY_ADR_CALVL_DLY_STEP_0
|
||||
|
||||
#define LPDDR4__DENALI_PHY_1074_READ_MASK 0x03FF010FU
|
||||
#define LPDDR4__DENALI_PHY_1074_WRITE_MASK 0x03FF010FU
|
||||
#define LPDDR4__DENALI_PHY_1074__PHY_ADR_CALVL_CAPTURE_CNT_0_MASK 0x0000000FU
|
||||
#define LPDDR4__DENALI_PHY_1074__PHY_ADR_CALVL_CAPTURE_CNT_0_SHIFT 0U
|
||||
#define LPDDR4__DENALI_PHY_1074__PHY_ADR_CALVL_CAPTURE_CNT_0_WIDTH 4U
|
||||
#define LPDDR4__PHY_ADR_CALVL_CAPTURE_CNT_0__REG DENALI_PHY_1074
|
||||
#define LPDDR4__PHY_ADR_CALVL_CAPTURE_CNT_0__FLD LPDDR4__DENALI_PHY_1074__PHY_ADR_CALVL_CAPTURE_CNT_0
|
||||
|
||||
#define LPDDR4__DENALI_PHY_1074__PHY_ADR_MEAS_DLY_STEP_ENABLE_0_MASK 0x00000100U
|
||||
#define LPDDR4__DENALI_PHY_1074__PHY_ADR_MEAS_DLY_STEP_ENABLE_0_SHIFT 8U
|
||||
#define LPDDR4__DENALI_PHY_1074__PHY_ADR_MEAS_DLY_STEP_ENABLE_0_WIDTH 1U
|
||||
#define LPDDR4__DENALI_PHY_1074__PHY_ADR_MEAS_DLY_STEP_ENABLE_0_WOCLR 0U
|
||||
#define LPDDR4__DENALI_PHY_1074__PHY_ADR_MEAS_DLY_STEP_ENABLE_0_WOSET 0U
|
||||
#define LPDDR4__PHY_ADR_MEAS_DLY_STEP_ENABLE_0__REG DENALI_PHY_1074
|
||||
#define LPDDR4__PHY_ADR_MEAS_DLY_STEP_ENABLE_0__FLD LPDDR4__DENALI_PHY_1074__PHY_ADR_MEAS_DLY_STEP_ENABLE_0
|
||||
|
||||
#define LPDDR4__DENALI_PHY_1074__PHY_ADR_DC_INIT_SLV_DELAY_0_MASK 0x03FF0000U
|
||||
#define LPDDR4__DENALI_PHY_1074__PHY_ADR_DC_INIT_SLV_DELAY_0_SHIFT 16U
|
||||
#define LPDDR4__DENALI_PHY_1074__PHY_ADR_DC_INIT_SLV_DELAY_0_WIDTH 10U
|
||||
#define LPDDR4__PHY_ADR_DC_INIT_SLV_DELAY_0__REG DENALI_PHY_1074
|
||||
#define LPDDR4__PHY_ADR_DC_INIT_SLV_DELAY_0__FLD LPDDR4__DENALI_PHY_1074__PHY_ADR_DC_INIT_SLV_DELAY_0
|
||||
|
||||
#define LPDDR4__DENALI_PHY_1075_READ_MASK 0x0000FF01U
|
||||
#define LPDDR4__DENALI_PHY_1075_WRITE_MASK 0x0000FF01U
|
||||
#define LPDDR4__DENALI_PHY_1075__PHY_ADR_DC_CALVL_ENABLE_0_MASK 0x00000001U
|
||||
#define LPDDR4__DENALI_PHY_1075__PHY_ADR_DC_CALVL_ENABLE_0_SHIFT 0U
|
||||
#define LPDDR4__DENALI_PHY_1075__PHY_ADR_DC_CALVL_ENABLE_0_WIDTH 1U
|
||||
#define LPDDR4__DENALI_PHY_1075__PHY_ADR_DC_CALVL_ENABLE_0_WOCLR 0U
|
||||
#define LPDDR4__DENALI_PHY_1075__PHY_ADR_DC_CALVL_ENABLE_0_WOSET 0U
|
||||
#define LPDDR4__PHY_ADR_DC_CALVL_ENABLE_0__REG DENALI_PHY_1075
|
||||
#define LPDDR4__PHY_ADR_DC_CALVL_ENABLE_0__FLD LPDDR4__DENALI_PHY_1075__PHY_ADR_DC_CALVL_ENABLE_0
|
||||
|
||||
#define LPDDR4__DENALI_PHY_1075__PHY_ADR_DC_DM_CLK_THRSHLD_0_MASK 0x0000FF00U
|
||||
#define LPDDR4__DENALI_PHY_1075__PHY_ADR_DC_DM_CLK_THRSHLD_0_SHIFT 8U
|
||||
#define LPDDR4__DENALI_PHY_1075__PHY_ADR_DC_DM_CLK_THRSHLD_0_WIDTH 8U
|
||||
#define LPDDR4__PHY_ADR_DC_DM_CLK_THRSHLD_0__REG DENALI_PHY_1075
|
||||
#define LPDDR4__PHY_ADR_DC_DM_CLK_THRSHLD_0__FLD LPDDR4__DENALI_PHY_1075__PHY_ADR_DC_DM_CLK_THRSHLD_0
|
||||
|
||||
#endif /* REG_LPDDR4_ADDRESS_SLICE_0_MACROS_H_ */
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
+7793
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,578 @@
|
||||
/* SPDX-License-Identifier: BSD-3-Clause */
|
||||
/**********************************************************************
|
||||
* Copyright (C) 2012-2019 Cadence Design Systems, Inc.
|
||||
**********************************************************************
|
||||
* WARNING: This file is auto-generated using api-generator utility.
|
||||
* api-generator: 12.02.13bb8d5
|
||||
* Do not edit it manually.
|
||||
**********************************************************************
|
||||
* Cadence Core Driver for LPDDR4.
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
#ifndef LPDDR4_IF_H
|
||||
#define LPDDR4_IF_H
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
/** @defgroup ConfigInfo Configuration and Hardware Operation Information
|
||||
* The following definitions specify the driver operation environment that
|
||||
* is defined by hardware configuration or client code. These defines are
|
||||
* located in the header file of the core driver.
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**********************************************************************
|
||||
* Defines
|
||||
**********************************************************************/
|
||||
/** Number of chip-selects */
|
||||
#define LPDDR4_MAX_CS (2U)
|
||||
|
||||
/** Number of accessible registers for controller. */
|
||||
#define LPDDR4_CTL_REG_COUNT (459U)
|
||||
|
||||
/** Number of accessible registers for PHY Independent Module. */
|
||||
#define LPDDR4_PHY_INDEP_REG_COUNT (300U)
|
||||
|
||||
/** Number of accessible registers for PHY. */
|
||||
#define LPDDR4_PHY_REG_COUNT (1423U)
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup DataStructure Dynamic Data Structures
|
||||
* This section defines the data structures used by the driver to provide
|
||||
* hardware information, modification and dynamic operation of the driver.
|
||||
* These data structures are defined in the header file of the core driver
|
||||
* and utilized by the API.
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**********************************************************************
|
||||
* Forward declarations
|
||||
**********************************************************************/
|
||||
typedef struct lpddr4_config_s lpddr4_config;
|
||||
typedef struct lpddr4_privatedata_s lpddr4_privatedata;
|
||||
typedef struct lpddr4_debuginfo_s lpddr4_debuginfo;
|
||||
typedef struct lpddr4_fspmoderegs_s lpddr4_fspmoderegs;
|
||||
typedef struct lpddr4_reginitdata_s lpddr4_reginitdata;
|
||||
|
||||
/**********************************************************************
|
||||
* Enumerations
|
||||
**********************************************************************/
|
||||
/** This is used to indicate whether the Controller, PHY, or PHY Independent module is addressed. */
|
||||
typedef enum
|
||||
{
|
||||
LPDDR4_CTL_REGS = 0U,
|
||||
LPDDR4_PHY_REGS = 1U,
|
||||
LPDDR4_PHY_INDEP_REGS = 2U
|
||||
} lpddr4_regblock;
|
||||
|
||||
/** Controller status or error interrupts. */
|
||||
typedef enum
|
||||
{
|
||||
LPDDR4_RESET_DONE = 0U,
|
||||
LPDDR4_BUS_ACCESS_ERROR = 1U,
|
||||
LPDDR4_MULTIPLE_BUS_ACCESS_ERROR = 2U,
|
||||
LPDDR4_ECC_MULTIPLE_CORR_ERROR = 3U,
|
||||
LPDDR4_ECC_MULTIPLE_UNCORR_ERROR = 4U,
|
||||
LPDDR4_ECC_WRITEBACK_EXEC_ERROR = 5U,
|
||||
LPDDR4_ECC_SCRUB_DONE = 6U,
|
||||
LPDDR4_ECC_SCRUB_ERROR = 7U,
|
||||
LPDDR4_PORT_COMMAND_ERROR = 8U,
|
||||
LPDDR4_MC_INIT_DONE = 9U,
|
||||
LPDDR4_LP_DONE = 10U,
|
||||
LPDDR4_BIST_DONE = 11U,
|
||||
LPDDR4_WRAP_ERROR = 12U,
|
||||
LPDDR4_INVALID_BURST_ERROR = 13U,
|
||||
LPDDR4_RDLVL_ERROR = 14U,
|
||||
LPDDR4_RDLVL_GATE_ERROR = 15U,
|
||||
LPDDR4_WRLVL_ERROR = 16U,
|
||||
LPDDR4_CA_TRAINING_ERROR = 17U,
|
||||
LPDDR4_DFI_UPDATE_ERROR = 18U,
|
||||
LPDDR4_MRR_ERROR = 19U,
|
||||
LPDDR4_PHY_MASTER_ERROR = 20U,
|
||||
LPDDR4_WRLVL_REQ = 21U,
|
||||
LPDDR4_RDLVL_REQ = 22U,
|
||||
LPDDR4_RDLVL_GATE_REQ = 23U,
|
||||
LPDDR4_CA_TRAINING_REQ = 24U,
|
||||
LPDDR4_LEVELING_DONE = 25U,
|
||||
LPDDR4_PHY_ERROR = 26U,
|
||||
LPDDR4_MR_READ_DONE = 27U,
|
||||
LPDDR4_TEMP_CHANGE = 28U,
|
||||
LPDDR4_TEMP_ALERT = 29U,
|
||||
LPDDR4_SW_DQS_COMPLETE = 30U,
|
||||
LPDDR4_DQS_OSC_BV_UPDATED = 31U,
|
||||
LPDDR4_DQS_OSC_OVERFLOW = 32U,
|
||||
LPDDR4_DQS_OSC_VAR_OUT = 33U,
|
||||
LPDDR4_MR_WRITE_DONE = 34U,
|
||||
LPDDR4_INHIBIT_DRAM_DONE = 35U,
|
||||
LPDDR4_DFI_INIT_STATE = 36U,
|
||||
LPDDR4_DLL_RESYNC_DONE = 37U,
|
||||
LPDDR4_TDFI_TO = 38U,
|
||||
LPDDR4_DFS_DONE = 39U,
|
||||
LPDDR4_DFS_STATUS = 40U,
|
||||
LPDDR4_REFRESH_STATUS = 41U,
|
||||
LPDDR4_ZQ_STATUS = 42U,
|
||||
LPDDR4_SW_REQ_MODE = 43U,
|
||||
LPDDR4_LOR_BITS = 44U
|
||||
} lpddr4_ctlinterrupt;
|
||||
|
||||
/** PHY Independent Module status or error interrupts. */
|
||||
typedef enum
|
||||
{
|
||||
LPDDR4_PHY_INDEP_INIT_DONE_BIT = 0U,
|
||||
LPDDR4_PHY_INDEP_CONTROL_ERROR_BIT = 1U,
|
||||
LPDDR4_PHY_INDEP_CA_PARITY_ERR_BIT = 2U,
|
||||
LPDDR4_PHY_INDEP_RDLVL_ERROR_BIT = 3U,
|
||||
LPDDR4_PHY_INDEP_RDLVL_GATE_ERROR_BIT = 4U,
|
||||
LPDDR4_PHY_INDEP_WRLVL_ERROR_BIT = 5U,
|
||||
LPDDR4_PHY_INDEP_CALVL_ERROR_BIT = 6U,
|
||||
LPDDR4_PHY_INDEP_WDQLVL_ERROR_BIT = 7U,
|
||||
LPDDR4_PHY_INDEP_UPDATE_ERROR_BIT = 8U,
|
||||
LPDDR4_PHY_INDEP_RDLVL_REQ_BIT = 9U,
|
||||
LPDDR4_PHY_INDEP_RDLVL_GATE_REQ_BIT = 10U,
|
||||
LPDDR4_PHY_INDEP_WRLVL_REQ_BIT = 11U,
|
||||
LPDDR4_PHY_INDEP_CALVL_REQ_BIT = 12U,
|
||||
LPDDR4_PHY_INDEP_WDQLVL_REQ_BIT = 13U,
|
||||
LPDDR4_PHY_INDEP_LVL_DONE_BIT = 14U,
|
||||
LPDDR4_PHY_INDEP_BIST_DONE_BIT = 15U,
|
||||
LPDDR4_PHY_INDEP_TDFI_INIT_TIME_OUT_BIT = 16U,
|
||||
LPDDR4_PHY_INDEP_DLL_LOCK_STATE_CHANGE_BIT = 17U
|
||||
} lpddr4_phyindepinterrupt;
|
||||
|
||||
/** List of informations and warnings from driver. */
|
||||
typedef enum
|
||||
{
|
||||
LPDDR4_DRV_NONE = 0U,
|
||||
LPDDR4_DRV_SOC_PLL_UPDATE = 1U
|
||||
} lpddr4_infotype;
|
||||
|
||||
/** Low power interface wake up timing parameters */
|
||||
typedef enum
|
||||
{
|
||||
LPDDR4_LPI_PD_WAKEUP_FN = 0U,
|
||||
LPDDR4_LPI_SR_SHORT_WAKEUP_FN = 1U,
|
||||
LPDDR4_LPI_SR_LONG_WAKEUP_FN = 2U,
|
||||
LPDDR4_LPI_SR_LONG_MCCLK_GATE_WAKEUP_FN = 3U,
|
||||
LPDDR4_LPI_SRPD_SHORT_WAKEUP_FN = 4U,
|
||||
LPDDR4_LPI_SRPD_LONG_WAKEUP_FN = 5U,
|
||||
LPDDR4_LPI_SRPD_LONG_MCCLK_GATE_WAKEUP_FN = 6U
|
||||
} lpddr4_lpiwakeupparam;
|
||||
|
||||
/** Half Datapath mode setting */
|
||||
typedef enum
|
||||
{
|
||||
LPDDR4_REDUC_ON = 0U,
|
||||
LPDDR4_REDUC_OFF = 1U
|
||||
} lpddr4_reducmode;
|
||||
|
||||
/** ECC Control parameter setting */
|
||||
typedef enum
|
||||
{
|
||||
LPDDR4_ECC_DISABLED = 0U,
|
||||
LPDDR4_ECC_ENABLED = 1U,
|
||||
LPDDR4_ECC_ERR_DETECT = 2U,
|
||||
LPDDR4_ECC_ERR_DETECT_CORRECT = 3U
|
||||
} lpddr4_eccenable;
|
||||
|
||||
/** Data Byte Inversion mode setting */
|
||||
typedef enum
|
||||
{
|
||||
LPDDR4_DBI_RD_ON = 0U,
|
||||
LPDDR4_DBI_RD_OFF = 1U,
|
||||
LPDDR4_DBI_WR_ON = 2U,
|
||||
LPDDR4_DBI_WR_OFF = 3U
|
||||
} lpddr4_dbimode;
|
||||
|
||||
/** Controller Frequency Set Point number */
|
||||
typedef enum
|
||||
{
|
||||
LPDDR4_FSP_0 = 0U,
|
||||
LPDDR4_FSP_1 = 1U,
|
||||
LPDDR4_FSP_2 = 2U
|
||||
} lpddr4_ctlfspnum;
|
||||
|
||||
/**********************************************************************
|
||||
* Callbacks
|
||||
**********************************************************************/
|
||||
/**
|
||||
* Reports informations and warnings that need to be communicated.
|
||||
* Params:
|
||||
* pD - driver state info specific to this instance.
|
||||
* infoType - Type of information.
|
||||
*/
|
||||
typedef void (*lpddr4_infocallback)(const lpddr4_privatedata* pd, lpddr4_infotype infotype);
|
||||
|
||||
/**
|
||||
* Reports interrupts received by the controller.
|
||||
* Params:
|
||||
* pD - driver state info specific to this instance.
|
||||
* ctlInterrupt - Interrupt raised
|
||||
* chipSelect - Chip for which interrupt raised
|
||||
*/
|
||||
typedef void (*lpddr4_ctlcallback)(const lpddr4_privatedata* pd, lpddr4_ctlinterrupt ctlinterrupt, uint8_t chipselect);
|
||||
|
||||
/**
|
||||
* Reports interrupts received by the PHY Independent Module.
|
||||
* Params:
|
||||
* privateData - driver state info specific to this instance.
|
||||
* phyIndepInterrupt - Interrupt raised
|
||||
* chipSelect - Chip for which interrupt raised
|
||||
*/
|
||||
typedef void (*lpddr4_phyindepcallback)(const lpddr4_privatedata* pd, lpddr4_phyindepinterrupt phyindepinterrupt, uint8_t chipselect);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup DriverFunctionAPI Driver Function API
|
||||
* Prototypes for the driver API functions. The user application can link statically to the
|
||||
* necessary API functions and call them directly.
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**********************************************************************
|
||||
* API methods
|
||||
**********************************************************************/
|
||||
|
||||
/**
|
||||
* Checks configuration object.
|
||||
* @param[in] config Driver/hardware configuration required.
|
||||
* @param[out] configSize Size of memory allocations required.
|
||||
* @return CDN_EOK on success (requirements structure filled).
|
||||
* @return ENOTSUP if configuration cannot be supported due to driver/hardware constraints.
|
||||
*/
|
||||
uint32_t lpddr4_probe(const lpddr4_config* config, uint16_t* configsize);
|
||||
|
||||
/**
|
||||
* Init function to be called after LPDDR4_probe() to set up the
|
||||
* driver configuration. Memory should be allocated for drv_data
|
||||
* (using the size determined using LPDDR4_probe) before calling this
|
||||
* API. init_settings should be initialised with base addresses for
|
||||
* PHY Indepenent Module, Controller and PHY before calling this
|
||||
* function. If callbacks are required for interrupt handling, these
|
||||
* should also be configured in init_settings.
|
||||
* @param[in] pD Driver state info specific to this instance.
|
||||
* @param[in] cfg Specifies driver/hardware configuration.
|
||||
* @return CDN_EOK on success
|
||||
* @return EINVAL if illegal/inconsistent values in cfg.
|
||||
* @return ENOTSUP if hardware has an inconsistent configuration or doesn't support feature(s) required by 'config' parameters.
|
||||
*/
|
||||
uint32_t lpddr4_init(lpddr4_privatedata* pd, const lpddr4_config* cfg);
|
||||
|
||||
/**
|
||||
* Start the driver.
|
||||
* @param[in] pD Driver state info specific to this instance.
|
||||
*/
|
||||
uint32_t lpddr4_start(const lpddr4_privatedata* pd);
|
||||
|
||||
/**
|
||||
* Read a register from the controller, PHY or PHY Independent Module
|
||||
* @param[in] pD Driver state info specific to this instance.
|
||||
* @param[in] cpp Indicates whether controller, PHY or PHY Independent Module register
|
||||
* @param[in] regOffset Register offset
|
||||
* @param[out] regValue Register value read
|
||||
* @return CDN_EOK on success.
|
||||
* @return EINVAL if regOffset if out of range or regValue is NULL
|
||||
*/
|
||||
uint32_t lpddr4_readreg(const lpddr4_privatedata* pd, lpddr4_regblock cpp, uint32_t regoffset, uint32_t* regvalue);
|
||||
|
||||
/**
|
||||
* Write a register in the controller, PHY or PHY Independent Module
|
||||
* @param[in] pD Driver state info specific to this instance.
|
||||
* @param[in] cpp Indicates whether controller, PHY or PHY Independent Module register
|
||||
* @param[in] regOffset Register offset
|
||||
* @param[in] regValue Register value to be written
|
||||
* @return CDN_EOK on success.
|
||||
* @return EINVAL if regOffset is out of range or regValue is NULL
|
||||
*/
|
||||
uint32_t lpddr4_writereg(const lpddr4_privatedata* pd, lpddr4_regblock cpp, uint32_t regoffset, uint32_t regvalue);
|
||||
|
||||
/**
|
||||
* Read a memory mode register from DRAM
|
||||
* @param[in] pD Driver state info specific to this instance.
|
||||
* @param[in] readModeRegVal Value to set in 'read_modereg' parameter.
|
||||
* @param[out] mmrValue Value which is read from memory mode register(mmr) for all devices.
|
||||
* @param[out] mmrStatus Status of mode register read(mrr) instruction.
|
||||
* @return CDN_EOK on success.
|
||||
* @return EINVAL if regNumber is out of range or regValue is NULL
|
||||
*/
|
||||
uint32_t lpddr4_getmmrregister(const lpddr4_privatedata* pd, uint32_t readmoderegval, uint64_t* mmrvalue, uint8_t* mmrstatus);
|
||||
|
||||
/**
|
||||
* Write a memory mode register in DRAM
|
||||
* @param[in] pD Driver state info specific to this instance.
|
||||
* @param[in] writeModeRegVal Value to set in 'write_modereg' parameter.
|
||||
* @param[out] mrwStatus Status of mode register write(mrw) instruction.
|
||||
* @return CDN_EOK on success.
|
||||
* @return EINVAL if regNumber is out of range or regValue is NULL
|
||||
*/
|
||||
uint32_t lpddr4_setmmrregister(const lpddr4_privatedata* pd, uint32_t writemoderegval, uint8_t* mrwstatus);
|
||||
|
||||
/**
|
||||
* Write a set of initialisation values to the controller registers
|
||||
* @param[in] pD Driver state info specific to this instance.
|
||||
* @param[in] regValues Register values to be written
|
||||
* @return CDN_EOK on success.
|
||||
* @return EINVAL if regValues is NULL
|
||||
*/
|
||||
uint32_t lpddr4_writectlconfig(const lpddr4_privatedata* pd, const lpddr4_reginitdata* regvalues);
|
||||
|
||||
/**
|
||||
* Write a set of initialisation values to the PHY registers
|
||||
* @param[in] pD Driver state info specific to this instance.
|
||||
* @param[in] regValues Register values to be written
|
||||
* @return CDN_EOK on success.
|
||||
* @return EINVAL if regValues is NULL
|
||||
*/
|
||||
uint32_t lpddr4_writephyconfig(const lpddr4_privatedata* pd, const lpddr4_reginitdata* regvalues);
|
||||
|
||||
/**
|
||||
* Write a set of initialisation values to the PHY Independent Module
|
||||
* registers
|
||||
* @param[in] pD Driver state info specific to this instance.
|
||||
* @param[in] regValues Register values to be written
|
||||
* @return CDN_EOK on success.
|
||||
* @return EINVAL if regValues is NULL
|
||||
*/
|
||||
uint32_t lpddr4_writephyindepconfig(const lpddr4_privatedata* pd, const lpddr4_reginitdata* regvalues);
|
||||
|
||||
/**
|
||||
* Read values of the controller registers in bulk (Set 'updateCtlReg'
|
||||
* to read) and store in memory.
|
||||
* @param[in] pD Driver state info specific to this instance.
|
||||
* @param[out] regValues Register values which are read
|
||||
* @return CDN_EOK on success.
|
||||
* @return EINVAL if regValues is NULL
|
||||
*/
|
||||
uint32_t lpddr4_readctlconfig(const lpddr4_privatedata* pd, lpddr4_reginitdata* regvalues);
|
||||
|
||||
/**
|
||||
* Read the values of the PHY module registers in bulk (Set
|
||||
* 'updatePhyReg' to read) and store in memory.
|
||||
* @param[in] pD Driver state info specific to this instance.
|
||||
* @param[out] regValues Register values which are read
|
||||
* @return CDN_EOK on success.
|
||||
* @return EINVAL if regValues is NULL
|
||||
*/
|
||||
uint32_t lpddr4_readphyconfig(const lpddr4_privatedata* pd, lpddr4_reginitdata* regvalues);
|
||||
|
||||
/**
|
||||
* Read the values of the PHY Independent module registers in bulk(Set
|
||||
* 'updatePhyIndepReg' to read) and store in memory.
|
||||
* @param[in] pD Driver state info specific to this instance.
|
||||
* @param[out] regValues Register values which are read
|
||||
* @return CDN_EOK on success.
|
||||
* @return EINVAL if regValues is NULL
|
||||
*/
|
||||
uint32_t lpddr4_readphyindepconfig(const lpddr4_privatedata* pd, lpddr4_reginitdata* regvalues);
|
||||
|
||||
/**
|
||||
* Read the current interrupt mask for the controller
|
||||
* @param[in] pD Driver state info specific to this instance.
|
||||
* @param[out] mask Value of interrupt mask
|
||||
* @return CDN_EOK on success.
|
||||
* @return EINVAL if mask pointer is NULL
|
||||
*/
|
||||
uint32_t lpddr4_getctlinterruptmask(const lpddr4_privatedata* pd, uint64_t* mask);
|
||||
|
||||
/**
|
||||
* Sets the interrupt mask for the controller
|
||||
* @param[in] pD Driver state info specific to this instance.
|
||||
* @param[in] mask Value of interrupt mask to be written
|
||||
* @return CDN_EOK on success.
|
||||
* @return EINVAL if mask pointer is NULL
|
||||
*/
|
||||
uint32_t lpddr4_setctlinterruptmask(const lpddr4_privatedata* pd, const uint64_t* mask);
|
||||
|
||||
/**
|
||||
* Check whether a specific controller interrupt is active
|
||||
* @param[in] pD Driver state info specific to this instance.
|
||||
* @param[in] intr Interrupt to be checked
|
||||
* @param[out] irqStatus Status of the interrupt, TRUE if active
|
||||
* @return CDN_EOK on success.
|
||||
* @return EINVAL if intr is not valid
|
||||
*/
|
||||
uint32_t lpddr4_checkctlinterrupt(const lpddr4_privatedata* pd, lpddr4_ctlinterrupt intr, bool* irqstatus);
|
||||
|
||||
/**
|
||||
* Acknowledge a specific controller interrupt
|
||||
* @param[in] pD Driver state info specific to this instance.
|
||||
* @param[in] intr Interrupt to be acknowledged
|
||||
* @return CDN_EOK on success.
|
||||
* @return EINVAL if intr is not valid
|
||||
*/
|
||||
uint32_t lpddr4_ackctlinterrupt(const lpddr4_privatedata* pd, lpddr4_ctlinterrupt intr);
|
||||
|
||||
/**
|
||||
* Read the current interrupt mask for the PHY Independent Module
|
||||
* @param[in] pD Driver state info specific to this instance.
|
||||
* @param[out] mask Value of interrupt mask
|
||||
* @return CDN_EOK on success.
|
||||
* @return EINVAL if mask pointer is NULL
|
||||
*/
|
||||
uint32_t lpddr4_getphyindepinterruptmask(const lpddr4_privatedata* pd, uint32_t* mask);
|
||||
|
||||
/**
|
||||
* Sets the interrupt mask for the PHY Independent Module
|
||||
* @param[in] pD Driver state info specific to this instance.
|
||||
* @param[in] mask Value of interrupt mask to be written
|
||||
* @return CDN_EOK on success.
|
||||
* @return EINVAL if mask pointer is NULL
|
||||
*/
|
||||
uint32_t lpddr4_setphyindepinterruptmask(const lpddr4_privatedata* pd, const uint32_t* mask);
|
||||
|
||||
/**
|
||||
* Check whether a specific PHY Independent Module interrupt is active
|
||||
* @param[in] pD Driver state info specific to this instance.
|
||||
* @param[in] intr Interrupt to be checked
|
||||
* @param[out] irqStatus Status of the interrupt, TRUE if active
|
||||
* @return CDN_EOK on success.
|
||||
* @return EINVAL if intr is not valid
|
||||
*/
|
||||
uint32_t lpddr4_checkphyindepinterrupt(const lpddr4_privatedata* pd, lpddr4_phyindepinterrupt intr, bool* irqstatus);
|
||||
|
||||
/**
|
||||
* Acknowledge a specific PHY Independent Module interrupt
|
||||
* @param[in] pD Driver state info specific to this instance.
|
||||
* @param[in] intr Interrupt to be acknowledged
|
||||
* @return CDN_EOK on success.
|
||||
* @return EINVAL if intr is not valid
|
||||
*/
|
||||
uint32_t lpddr4_ackphyindepinterrupt(const lpddr4_privatedata* pd, lpddr4_phyindepinterrupt intr);
|
||||
|
||||
/**
|
||||
* Retrieve status information after a failed init. The
|
||||
* DebugStructInfo will be filled in with error codes which can be
|
||||
* referenced against the driver documentation for further details.
|
||||
* @param[in] pD Driver state info specific to this instance.
|
||||
* @param[out] debugInfo status
|
||||
* @return CDN_EOK on success.
|
||||
* @return EINVAL if debugInfo is NULL
|
||||
*/
|
||||
uint32_t lpddr4_getdebuginitinfo(const lpddr4_privatedata* pd, lpddr4_debuginfo* debuginfo);
|
||||
|
||||
/**
|
||||
* Get the current value of Low power Interface wake up time.
|
||||
* @param[in] pD Driver state info specific to this instance.
|
||||
* @param[in] lpiWakeUpParam LPI timing parameter
|
||||
* @param[in] fspNum Frequency copy
|
||||
* @param[out] cycles Timing value(in cycles)
|
||||
* @return CDN_EOK on success.
|
||||
* @return EINVAL if powerMode is NULL
|
||||
*/
|
||||
uint32_t lpddr4_getlpiwakeuptime(const lpddr4_privatedata* pd, const lpddr4_lpiwakeupparam* lpiwakeupparam, const lpddr4_ctlfspnum* fspnum, uint32_t* cycles);
|
||||
|
||||
/**
|
||||
* Set the current value of Low power Interface wake up time.
|
||||
* @param[in] pD Driver state info specific to this instance.
|
||||
* @param[in] lpiWakeUpParam LPI timing parameter
|
||||
* @param[in] fspNum Frequency copy
|
||||
* @param[in] cycles Timing value(in cycles)
|
||||
* @return CDN_EOK on success.
|
||||
* @return EINVAL if powerMode is NULL
|
||||
*/
|
||||
uint32_t lpddr4_setlpiwakeuptime(const lpddr4_privatedata* pd, const lpddr4_lpiwakeupparam* lpiwakeupparam, const lpddr4_ctlfspnum* fspnum, const uint32_t* cycles);
|
||||
|
||||
/**
|
||||
* Get the current value for ECC auto correction
|
||||
* @param[in] pD Driver state info specific to this instance.
|
||||
* @param[out] eccParam ECC parameter setting
|
||||
* @return CDN_EOK on success.
|
||||
* @return EINVAL if on_off is NULL
|
||||
*/
|
||||
uint32_t lpddr4_geteccenable(const lpddr4_privatedata* pd, lpddr4_eccenable* eccparam);
|
||||
|
||||
/**
|
||||
* Set the value for ECC auto correction. This API must be called
|
||||
* before startup of memory.
|
||||
* @param[in] pD Driver state info specific to this instance.
|
||||
* @param[in] eccParam ECC control parameter setting
|
||||
* @return CDN_EOK on success.
|
||||
* @return EINVAL if on_off is NULL
|
||||
*/
|
||||
uint32_t lpddr4_seteccenable(const lpddr4_privatedata* pd, const lpddr4_eccenable* eccparam);
|
||||
|
||||
/**
|
||||
* Get the current value for the Half Datapath option
|
||||
* @param[in] pD Driver state info specific to this instance.
|
||||
* @param[out] mode Half Datapath setting
|
||||
* @return CDN_EOK on success.
|
||||
* @return EINVAL if mode is NULL
|
||||
*/
|
||||
uint32_t lpddr4_getreducmode(const lpddr4_privatedata* pd, lpddr4_reducmode* mode);
|
||||
|
||||
/**
|
||||
* Set the value for the Half Datapath option. This API must be
|
||||
* called before startup of memory.
|
||||
* @param[in] pD Driver state info specific to this instance.
|
||||
* @param[in] mode Half Datapath setting
|
||||
* @return CDN_EOK on success.
|
||||
* @return EINVAL if mode is NULL
|
||||
*/
|
||||
uint32_t lpddr4_setreducmode(const lpddr4_privatedata* pd, const lpddr4_reducmode* mode);
|
||||
|
||||
/**
|
||||
* Get the current value for Data Bus Inversion setting. This will be
|
||||
* compared with the current DRAM setting using the MR3 register.
|
||||
* @param[in] pD Driver state info specific to this instance.
|
||||
* @param[out] on_off DBI read value
|
||||
* @return CDN_EOK on success.
|
||||
* @return EINVAL if on_off is NULL
|
||||
*/
|
||||
uint32_t lpddr4_getdbireadmode(const lpddr4_privatedata* pd, bool* on_off);
|
||||
|
||||
/**
|
||||
* Get the current value for Data Bus Inversion setting. This will be
|
||||
* compared with the current DRAM setting using the MR3 register.
|
||||
* @param[in] pD Driver state info specific to this instance.
|
||||
* @param[out] on_off DBI write value
|
||||
* @return CDN_EOK on success.
|
||||
* @return EINVAL if on_off is NULL
|
||||
*/
|
||||
uint32_t lpddr4_getdbiwritemode(const lpddr4_privatedata* pd, bool* on_off);
|
||||
|
||||
/**
|
||||
* Set the mode for Data Bus Inversion. This will also be set in DRAM
|
||||
* using the MR3 controller register. This API must be called before
|
||||
* startup of memory.
|
||||
* @param[in] pD Driver state info specific to this instance.
|
||||
* @param[in] mode status
|
||||
* @return CDN_EOK on success.
|
||||
* @return EINVAL if mode is NULL
|
||||
*/
|
||||
uint32_t lpddr4_setdbimode(const lpddr4_privatedata* pd, const lpddr4_dbimode* mode);
|
||||
|
||||
/**
|
||||
* Get the current value for the refresh rate (reading Refresh per
|
||||
* command timing).
|
||||
* @param[in] pD Driver state info specific to this instance.
|
||||
* @param[in] fspNum Frequency set number
|
||||
* @param[out] cycles Refresh rate (in cycles)
|
||||
* @return CDN_EOK on success.
|
||||
* @return EINVAL if rate is NULL
|
||||
*/
|
||||
uint32_t lpddr4_getrefreshrate(const lpddr4_privatedata* pd, const lpddr4_ctlfspnum* fspnum, uint32_t* cycles);
|
||||
|
||||
/**
|
||||
* Set the refresh rate (writing Refresh per command timing).
|
||||
* @param[in] pD Driver state info specific to this instance.
|
||||
* @param[in] fspNum Frequency set number
|
||||
* @param[in] cycles Refresh rate (in cycles)
|
||||
* @return CDN_EOK on success.
|
||||
* @return EINVAL if rate is NULL
|
||||
*/
|
||||
uint32_t lpddr4_setrefreshrate(const lpddr4_privatedata* pd, const lpddr4_ctlfspnum* fspnum, const uint32_t* cycles);
|
||||
|
||||
/**
|
||||
* Handle Refreshing per chip select
|
||||
* @param[in] pD Driver state info specific to this instance.
|
||||
* @param[in] trefInterval status
|
||||
* @return CDN_EOK on success.
|
||||
* @return EINVAL if chipSelect is invalid
|
||||
*/
|
||||
uint32_t lpddr4_refreshperchipselect(const lpddr4_privatedata* pd, const uint32_t trefinterval);
|
||||
|
||||
#endif /* LPDDR4_IF_H */
|
||||
@@ -0,0 +1,55 @@
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
/**********************************************************************
|
||||
* Copyright (C) 2012-2019 Cadence Design Systems, Inc.
|
||||
**********************************************************************
|
||||
* WARNING: This file is auto-generated using api-generator utility.
|
||||
* api-generator: 12.02.13bb8d5
|
||||
* Do not edit it manually.
|
||||
**********************************************************************
|
||||
* Cadence Core Driver for LPDDR4.
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
#include "lpddr4_obj_if.h"
|
||||
|
||||
LPDDR4_OBJ *lpddr4_getinstance(void)
|
||||
{
|
||||
static LPDDR4_OBJ driver = {
|
||||
.probe = lpddr4_probe,
|
||||
.init = lpddr4_init,
|
||||
.start = lpddr4_start,
|
||||
.readreg = lpddr4_readreg,
|
||||
.writereg = lpddr4_writereg,
|
||||
.getmmrregister = lpddr4_getmmrregister,
|
||||
.setmmrregister = lpddr4_setmmrregister,
|
||||
.writectlconfig = lpddr4_writectlconfig,
|
||||
.writephyconfig = lpddr4_writephyconfig,
|
||||
.writephyindepconfig = lpddr4_writephyindepconfig,
|
||||
.readctlconfig = lpddr4_readctlconfig,
|
||||
.readphyconfig = lpddr4_readphyconfig,
|
||||
.readphyindepconfig = lpddr4_readphyindepconfig,
|
||||
.getctlinterruptmask = lpddr4_getctlinterruptmask,
|
||||
.setctlinterruptmask = lpddr4_setctlinterruptmask,
|
||||
.checkctlinterrupt = lpddr4_checkctlinterrupt,
|
||||
.ackctlinterrupt = lpddr4_ackctlinterrupt,
|
||||
.getphyindepinterruptmask = lpddr4_getphyindepinterruptmask,
|
||||
.setphyindepinterruptmask = lpddr4_setphyindepinterruptmask,
|
||||
.checkphyindepinterrupt = lpddr4_checkphyindepinterrupt,
|
||||
.ackphyindepinterrupt = lpddr4_ackphyindepinterrupt,
|
||||
.getdebuginitinfo = lpddr4_getdebuginitinfo,
|
||||
.getlpiwakeuptime = lpddr4_getlpiwakeuptime,
|
||||
.setlpiwakeuptime = lpddr4_setlpiwakeuptime,
|
||||
.geteccenable = lpddr4_geteccenable,
|
||||
.seteccenable = lpddr4_seteccenable,
|
||||
.getreducmode = lpddr4_getreducmode,
|
||||
.setreducmode = lpddr4_setreducmode,
|
||||
.getdbireadmode = lpddr4_getdbireadmode,
|
||||
.getdbiwritemode = lpddr4_getdbiwritemode,
|
||||
.setdbimode = lpddr4_setdbimode,
|
||||
.getrefreshrate = lpddr4_getrefreshrate,
|
||||
.setrefreshrate = lpddr4_setrefreshrate,
|
||||
.refreshperchipselect = lpddr4_refreshperchipselect,
|
||||
};
|
||||
|
||||
return &driver;
|
||||
}
|
||||
@@ -0,0 +1,383 @@
|
||||
/* SPDX-License-Identifier: BSD-3-Clause */
|
||||
/**********************************************************************
|
||||
* Copyright (C) 2012-2019 Cadence Design Systems, Inc.
|
||||
**********************************************************************
|
||||
* WARNING: This file is auto-generated using api-generator utility.
|
||||
* api-generator: 12.02.13bb8d5
|
||||
* Do not edit it manually.
|
||||
**********************************************************************
|
||||
* Cadence Core Driver for LPDDR4.
|
||||
**********************************************************************
|
||||
*/
|
||||
#ifndef LPDDR4_OBJ_IF_H
|
||||
#define LPDDR4_OBJ_IF_H
|
||||
|
||||
#include "lpddr4_if.h"
|
||||
|
||||
/** @defgroup DriverObject Driver API Object
|
||||
* API listing for the driver. The API is contained in the object as
|
||||
* function pointers in the object structure. As the actual functions
|
||||
* resides in the Driver Object, the client software must first use the
|
||||
* global GetInstance function to obtain the Driver Object Pointer.
|
||||
* The actual APIs then can be invoked using obj->(api_name)() syntax.
|
||||
* These functions are defined in the header file of the core driver
|
||||
* and utilized by the API.
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**********************************************************************
|
||||
* API methods
|
||||
**********************************************************************/
|
||||
typedef struct lpddr4_obj_s
|
||||
{
|
||||
/**
|
||||
* Checks configuration object.
|
||||
* @param[in] config Driver/hardware configuration required.
|
||||
* @param[out] configSize Size of memory allocations required.
|
||||
* @return CDN_EOK on success (requirements structure filled).
|
||||
* @return ENOTSUP if configuration cannot be supported due to driver/hardware constraints.
|
||||
*/
|
||||
uint32_t (*probe)(const lpddr4_config* config, uint16_t* configsize);
|
||||
|
||||
/**
|
||||
* Init function to be called after LPDDR4_probe() to set up the
|
||||
* driver configuration. Memory should be allocated for drv_data
|
||||
* (using the size determined using LPDDR4_probe) before calling
|
||||
* this API. init_settings should be initialised with base addresses
|
||||
* for PHY Indepenent Module, Controller and PHY before calling this
|
||||
* function. If callbacks are required for interrupt handling, these
|
||||
* should also be configured in init_settings.
|
||||
* @param[in] pD Driver state info specific to this instance.
|
||||
* @param[in] cfg Specifies driver/hardware configuration.
|
||||
* @return CDN_EOK on success
|
||||
* @return EINVAL if illegal/inconsistent values in cfg.
|
||||
* @return ENOTSUP if hardware has an inconsistent configuration or doesn't support feature(s) required by 'config' parameters.
|
||||
*/
|
||||
uint32_t (*init)(lpddr4_privatedata* pd, const lpddr4_config* cfg);
|
||||
|
||||
/**
|
||||
* Start the driver.
|
||||
* @param[in] pD Driver state info specific to this instance.
|
||||
*/
|
||||
uint32_t (*start)(const lpddr4_privatedata* pd);
|
||||
|
||||
/**
|
||||
* Read a register from the controller, PHY or PHY Independent Module
|
||||
* @param[in] pD Driver state info specific to this instance.
|
||||
* @param[in] cpp Indicates whether controller, PHY or PHY Independent Module register
|
||||
* @param[in] regOffset Register offset
|
||||
* @param[out] regValue Register value read
|
||||
* @return CDN_EOK on success.
|
||||
* @return EINVAL if regOffset if out of range or regValue is NULL
|
||||
*/
|
||||
uint32_t (*readreg)(const lpddr4_privatedata* pd, lpddr4_regblock cpp, uint32_t regoffset, uint32_t* regvalue);
|
||||
|
||||
/**
|
||||
* Write a register in the controller, PHY or PHY Independent Module
|
||||
* @param[in] pD Driver state info specific to this instance.
|
||||
* @param[in] cpp Indicates whether controller, PHY or PHY Independent Module register
|
||||
* @param[in] regOffset Register offset
|
||||
* @param[in] regValue Register value to be written
|
||||
* @return CDN_EOK on success.
|
||||
* @return EINVAL if regOffset is out of range or regValue is NULL
|
||||
*/
|
||||
uint32_t (*writereg)(const lpddr4_privatedata* pd, lpddr4_regblock cpp, uint32_t regoffset, uint32_t regvalue);
|
||||
|
||||
/**
|
||||
* Read a memory mode register from DRAM
|
||||
* @param[in] pD Driver state info specific to this instance.
|
||||
* @param[in] readModeRegVal Value to set in 'read_modereg' parameter.
|
||||
* @param[out] mmrValue Value which is read from memory mode register(mmr) for all devices.
|
||||
* @param[out] mmrStatus Status of mode register read(mrr) instruction.
|
||||
* @return CDN_EOK on success.
|
||||
* @return EINVAL if regNumber is out of range or regValue is NULL
|
||||
*/
|
||||
uint32_t (*getmmrregister)(const lpddr4_privatedata* pd, uint32_t readmoderegval, uint64_t* mmrvalue, uint8_t* mmrstatus);
|
||||
|
||||
/**
|
||||
* Write a memory mode register in DRAM
|
||||
* @param[in] pD Driver state info specific to this instance.
|
||||
* @param[in] writeModeRegVal Value to set in 'write_modereg' parameter.
|
||||
* @param[out] mrwStatus Status of mode register write(mrw) instruction.
|
||||
* @return CDN_EOK on success.
|
||||
* @return EINVAL if regNumber is out of range or regValue is NULL
|
||||
*/
|
||||
uint32_t (*setmmrregister)(const lpddr4_privatedata* pd, uint32_t writemoderegval, uint8_t* mrwstatus);
|
||||
|
||||
/**
|
||||
* Write a set of initialisation values to the controller registers
|
||||
* @param[in] pD Driver state info specific to this instance.
|
||||
* @param[in] regValues Register values to be written
|
||||
* @return CDN_EOK on success.
|
||||
* @return EINVAL if regValues is NULL
|
||||
*/
|
||||
uint32_t (*writectlconfig)(const lpddr4_privatedata* pd, const lpddr4_reginitdata* regvalues);
|
||||
|
||||
/**
|
||||
* Write a set of initialisation values to the PHY registers
|
||||
* @param[in] pD Driver state info specific to this instance.
|
||||
* @param[in] regValues Register values to be written
|
||||
* @return CDN_EOK on success.
|
||||
* @return EINVAL if regValues is NULL
|
||||
*/
|
||||
uint32_t (*writephyconfig)(const lpddr4_privatedata* pd, const lpddr4_reginitdata* regvalues);
|
||||
|
||||
/**
|
||||
* Write a set of initialisation values to the PHY Independent Module
|
||||
* registers
|
||||
* @param[in] pD Driver state info specific to this instance.
|
||||
* @param[in] regValues Register values to be written
|
||||
* @return CDN_EOK on success.
|
||||
* @return EINVAL if regValues is NULL
|
||||
*/
|
||||
uint32_t (*writephyindepconfig)(const lpddr4_privatedata* pd, const lpddr4_reginitdata* regvalues);
|
||||
|
||||
/**
|
||||
* Read values of the controller registers in bulk (Set
|
||||
* 'updateCtlReg' to read) and store in memory.
|
||||
* @param[in] pD Driver state info specific to this instance.
|
||||
* @param[out] regValues Register values which are read
|
||||
* @return CDN_EOK on success.
|
||||
* @return EINVAL if regValues is NULL
|
||||
*/
|
||||
uint32_t (*readctlconfig)(const lpddr4_privatedata* pd, lpddr4_reginitdata* regvalues);
|
||||
|
||||
/**
|
||||
* Read the values of the PHY module registers in bulk (Set
|
||||
* 'updatePhyReg' to read) and store in memory.
|
||||
* @param[in] pD Driver state info specific to this instance.
|
||||
* @param[out] regValues Register values which are read
|
||||
* @return CDN_EOK on success.
|
||||
* @return EINVAL if regValues is NULL
|
||||
*/
|
||||
uint32_t (*readphyconfig)(const lpddr4_privatedata* pd, lpddr4_reginitdata* regvalues);
|
||||
|
||||
/**
|
||||
* Read the values of the PHY Independent module registers in
|
||||
* bulk(Set 'updatePhyIndepReg' to read) and store in memory.
|
||||
* @param[in] pD Driver state info specific to this instance.
|
||||
* @param[out] regValues Register values which are read
|
||||
* @return CDN_EOK on success.
|
||||
* @return EINVAL if regValues is NULL
|
||||
*/
|
||||
uint32_t (*readphyindepconfig)(const lpddr4_privatedata* pd, lpddr4_reginitdata* regvalues);
|
||||
|
||||
/**
|
||||
* Read the current interrupt mask for the controller
|
||||
* @param[in] pD Driver state info specific to this instance.
|
||||
* @param[out] mask Value of interrupt mask
|
||||
* @return CDN_EOK on success.
|
||||
* @return EINVAL if mask pointer is NULL
|
||||
*/
|
||||
uint32_t (*getctlinterruptmask)(const lpddr4_privatedata* pd, uint64_t* mask);
|
||||
|
||||
/**
|
||||
* Sets the interrupt mask for the controller
|
||||
* @param[in] pD Driver state info specific to this instance.
|
||||
* @param[in] mask Value of interrupt mask to be written
|
||||
* @return CDN_EOK on success.
|
||||
* @return EINVAL if mask pointer is NULL
|
||||
*/
|
||||
uint32_t (*setctlinterruptmask)(const lpddr4_privatedata* pd, const uint64_t* mask);
|
||||
|
||||
/**
|
||||
* Check whether a specific controller interrupt is active
|
||||
* @param[in] pD Driver state info specific to this instance.
|
||||
* @param[in] intr Interrupt to be checked
|
||||
* @param[out] irqStatus Status of the interrupt, TRUE if active
|
||||
* @return CDN_EOK on success.
|
||||
* @return EINVAL if intr is not valid
|
||||
*/
|
||||
uint32_t (*checkctlinterrupt)(const lpddr4_privatedata* pd, lpddr4_ctlinterrupt intr, bool* irqstatus);
|
||||
|
||||
/**
|
||||
* Acknowledge a specific controller interrupt
|
||||
* @param[in] pD Driver state info specific to this instance.
|
||||
* @param[in] intr Interrupt to be acknowledged
|
||||
* @return CDN_EOK on success.
|
||||
* @return EINVAL if intr is not valid
|
||||
*/
|
||||
uint32_t (*ackctlinterrupt)(const lpddr4_privatedata* pd, lpddr4_ctlinterrupt intr);
|
||||
|
||||
/**
|
||||
* Read the current interrupt mask for the PHY Independent Module
|
||||
* @param[in] pD Driver state info specific to this instance.
|
||||
* @param[out] mask Value of interrupt mask
|
||||
* @return CDN_EOK on success.
|
||||
* @return EINVAL if mask pointer is NULL
|
||||
*/
|
||||
uint32_t (*getphyindepinterruptmask)(const lpddr4_privatedata* pd, uint32_t* mask);
|
||||
|
||||
/**
|
||||
* Sets the interrupt mask for the PHY Independent Module
|
||||
* @param[in] pD Driver state info specific to this instance.
|
||||
* @param[in] mask Value of interrupt mask to be written
|
||||
* @return CDN_EOK on success.
|
||||
* @return EINVAL if mask pointer is NULL
|
||||
*/
|
||||
uint32_t (*setphyindepinterruptmask)(const lpddr4_privatedata* pd, const uint32_t* mask);
|
||||
|
||||
/**
|
||||
* Check whether a specific PHY Independent Module interrupt is
|
||||
* active
|
||||
* @param[in] pD Driver state info specific to this instance.
|
||||
* @param[in] intr Interrupt to be checked
|
||||
* @param[out] irqStatus Status of the interrupt, TRUE if active
|
||||
* @return CDN_EOK on success.
|
||||
* @return EINVAL if intr is not valid
|
||||
*/
|
||||
uint32_t (*checkphyindepinterrupt)(const lpddr4_privatedata* pd, lpddr4_phyindepinterrupt intr, bool* irqstatus);
|
||||
|
||||
/**
|
||||
* Acknowledge a specific PHY Independent Module interrupt
|
||||
* @param[in] pD Driver state info specific to this instance.
|
||||
* @param[in] intr Interrupt to be acknowledged
|
||||
* @return CDN_EOK on success.
|
||||
* @return EINVAL if intr is not valid
|
||||
*/
|
||||
uint32_t (*ackphyindepinterrupt)(const lpddr4_privatedata* pd, lpddr4_phyindepinterrupt intr);
|
||||
|
||||
/**
|
||||
* Retrieve status information after a failed init. The
|
||||
* DebugStructInfo will be filled in with error codes which can be
|
||||
* referenced against the driver documentation for further details.
|
||||
* @param[in] pD Driver state info specific to this instance.
|
||||
* @param[out] debugInfo status
|
||||
* @return CDN_EOK on success.
|
||||
* @return EINVAL if debugInfo is NULL
|
||||
*/
|
||||
uint32_t (*getdebuginitinfo)(const lpddr4_privatedata* pd, lpddr4_debuginfo* debuginfo);
|
||||
|
||||
/**
|
||||
* Get the current value of Low power Interface wake up time.
|
||||
* @param[in] pD Driver state info specific to this instance.
|
||||
* @param[in] lpiWakeUpParam LPI timing parameter
|
||||
* @param[in] fspNum Frequency copy
|
||||
* @param[out] cycles Timing value(in cycles)
|
||||
* @return CDN_EOK on success.
|
||||
* @return EINVAL if powerMode is NULL
|
||||
*/
|
||||
uint32_t (*getlpiwakeuptime)(const lpddr4_privatedata* pd, const lpddr4_lpiwakeupparam* lpiwakeupparam, const lpddr4_ctlfspnum* fspnum, uint32_t* cycles);
|
||||
|
||||
/**
|
||||
* Set the current value of Low power Interface wake up time.
|
||||
* @param[in] pD Driver state info specific to this instance.
|
||||
* @param[in] lpiWakeUpParam LPI timing parameter
|
||||
* @param[in] fspNum Frequency copy
|
||||
* @param[in] cycles Timing value(in cycles)
|
||||
* @return CDN_EOK on success.
|
||||
* @return EINVAL if powerMode is NULL
|
||||
*/
|
||||
uint32_t (*setlpiwakeuptime)(const lpddr4_privatedata* pd, const lpddr4_lpiwakeupparam* lpiwakeupparam, const lpddr4_ctlfspnum* fspnum, const uint32_t* cycles);
|
||||
|
||||
/**
|
||||
* Get the current value for ECC auto correction
|
||||
* @param[in] pD Driver state info specific to this instance.
|
||||
* @param[out] eccParam ECC parameter setting
|
||||
* @return CDN_EOK on success.
|
||||
* @return EINVAL if on_off is NULL
|
||||
*/
|
||||
uint32_t (*geteccenable)(const lpddr4_privatedata* pd, lpddr4_eccenable* eccparam);
|
||||
|
||||
/**
|
||||
* Set the value for ECC auto correction. This API must be called
|
||||
* before startup of memory.
|
||||
* @param[in] pD Driver state info specific to this instance.
|
||||
* @param[in] eccParam ECC control parameter setting
|
||||
* @return CDN_EOK on success.
|
||||
* @return EINVAL if on_off is NULL
|
||||
*/
|
||||
uint32_t (*seteccenable)(const lpddr4_privatedata* pd, const lpddr4_eccenable* eccparam);
|
||||
|
||||
/**
|
||||
* Get the current value for the Half Datapath option
|
||||
* @param[in] pD Driver state info specific to this instance.
|
||||
* @param[out] mode Half Datapath setting
|
||||
* @return CDN_EOK on success.
|
||||
* @return EINVAL if mode is NULL
|
||||
*/
|
||||
uint32_t (*getreducmode)(const lpddr4_privatedata* pd, lpddr4_reducmode* mode);
|
||||
|
||||
/**
|
||||
* Set the value for the Half Datapath option. This API must be
|
||||
* called before startup of memory.
|
||||
* @param[in] pD Driver state info specific to this instance.
|
||||
* @param[in] mode Half Datapath setting
|
||||
* @return CDN_EOK on success.
|
||||
* @return EINVAL if mode is NULL
|
||||
*/
|
||||
uint32_t (*setreducmode)(const lpddr4_privatedata* pd, const lpddr4_reducmode* mode);
|
||||
|
||||
/**
|
||||
* Get the current value for Data Bus Inversion setting. This will
|
||||
* be compared with the current DRAM setting using the MR3
|
||||
* register.
|
||||
* @param[in] pD Driver state info specific to this instance.
|
||||
* @param[out] on_off DBI read value
|
||||
* @return CDN_EOK on success.
|
||||
* @return EINVAL if on_off is NULL
|
||||
*/
|
||||
uint32_t (*getdbireadmode)(const lpddr4_privatedata* pd, bool* on_off);
|
||||
|
||||
/**
|
||||
* Get the current value for Data Bus Inversion setting. This will
|
||||
* be compared with the current DRAM setting using the MR3
|
||||
* register.
|
||||
* @param[in] pD Driver state info specific to this instance.
|
||||
* @param[out] on_off DBI write value
|
||||
* @return CDN_EOK on success.
|
||||
* @return EINVAL if on_off is NULL
|
||||
*/
|
||||
uint32_t (*getdbiwritemode)(const lpddr4_privatedata* pd, bool* on_off);
|
||||
|
||||
/**
|
||||
* Set the mode for Data Bus Inversion. This will also be set in DRAM
|
||||
* using the MR3 controller register. This API must be called
|
||||
* before startup of memory.
|
||||
* @param[in] pD Driver state info specific to this instance.
|
||||
* @param[in] mode status
|
||||
* @return CDN_EOK on success.
|
||||
* @return EINVAL if mode is NULL
|
||||
*/
|
||||
uint32_t (*setdbimode)(const lpddr4_privatedata* pd, const lpddr4_dbimode* mode);
|
||||
|
||||
/**
|
||||
* Get the current value for the refresh rate (reading Refresh per
|
||||
* command timing).
|
||||
* @param[in] pD Driver state info specific to this instance.
|
||||
* @param[in] fspNum Frequency set number
|
||||
* @param[out] cycles Refresh rate (in cycles)
|
||||
* @return CDN_EOK on success.
|
||||
* @return EINVAL if rate is NULL
|
||||
*/
|
||||
uint32_t (*getrefreshrate)(const lpddr4_privatedata* pd, const lpddr4_ctlfspnum* fspnum, uint32_t* cycles);
|
||||
|
||||
/**
|
||||
* Set the refresh rate (writing Refresh per command timing).
|
||||
* @param[in] pD Driver state info specific to this instance.
|
||||
* @param[in] fspNum Frequency set number
|
||||
* @param[in] cycles Refresh rate (in cycles)
|
||||
* @return CDN_EOK on success.
|
||||
* @return EINVAL if rate is NULL
|
||||
*/
|
||||
uint32_t (*setrefreshrate)(const lpddr4_privatedata* pd, const lpddr4_ctlfspnum* fspnum, const uint32_t* cycles);
|
||||
|
||||
/**
|
||||
* Handle Refreshing per chip select
|
||||
* @param[in] pD Driver state info specific to this instance.
|
||||
* @param[in] trefInterval status
|
||||
* @return CDN_EOK on success.
|
||||
* @return EINVAL if chipSelect is invalid
|
||||
*/
|
||||
uint32_t (*refreshperchipselect)(const lpddr4_privatedata* pd, const uint32_t trefinterval);
|
||||
|
||||
} LPDDR4_OBJ;
|
||||
|
||||
/**
|
||||
* In order to access the LPDDR4 APIs, the upper layer software must call
|
||||
* this global function to obtain the pointer to the driver object.
|
||||
* @return LPDDR4_OBJ* Driver Object Pointer
|
||||
*/
|
||||
extern LPDDR4_OBJ *lpddr4_getinstance(void);
|
||||
|
||||
#endif /* LPDDR4_OBJ_IF_H */
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,56 @@
|
||||
/* SPDX-License-Identifier: BSD-3-Clause */
|
||||
/**********************************************************************
|
||||
* Copyright (C) 2012-2018 Cadence Design Systems, Inc.
|
||||
* Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com/
|
||||
**********************************************************************
|
||||
* Cadence Core Driver for LPDDR4.
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
#ifndef LPDDR4_PRIV_H
|
||||
#define LPDDR4_PRIV_H
|
||||
|
||||
#define PRODUCT_ID (0x1046U)
|
||||
#define VERSION_0 (0x54d5da40U)
|
||||
#define VERSION_1 (0xc1865a1U)
|
||||
|
||||
#define BIT_MASK (0x1U)
|
||||
#define BYTE_MASK (0xffU)
|
||||
#define NIBBLE_MASK (0xfU)
|
||||
|
||||
#define WORD_SHIFT (32U)
|
||||
#define WORD_MASK (0xffffffffU)
|
||||
#define SLICE_WIDTH (0x100)
|
||||
/* Number of Data slices */
|
||||
#define DSLICE_NUM (4U)
|
||||
/*Number of Address Slices */
|
||||
#define ASLICE_NUM (1U)
|
||||
|
||||
/* Number of accessible registers in each slice */
|
||||
#define DSLICE0_REG_COUNT (140U)
|
||||
#define DSLICE1_REG_COUNT (140U)
|
||||
#define DSLICE2_REG_COUNT (140U)
|
||||
#define DSLICE3_REG_COUNT (140U)
|
||||
#define ASLICE0_REG_COUNT (52U)
|
||||
#define PHY_CORE_REG_COUNT (140U)
|
||||
|
||||
#define CTL_OFFSET 0
|
||||
#define PI_OFFSET (((uint32_t)1) << 11)
|
||||
#define PHY_OFFSET (((uint32_t)1) << 12)
|
||||
|
||||
/* BIT[17] on INT_MASK_1 register. */
|
||||
#define CTL_INT_MASK_ALL ((uint32_t)LPDDR4_LOR_BITS - WORD_SHIFT)
|
||||
|
||||
/* Init Error information bits */
|
||||
#define PLL_READY (0x3U)
|
||||
#define IO_CALIB_DONE ((uint32_t)0x1U << 23U)
|
||||
#define IO_CALIB_FIELD ((uint32_t)NIBBLE_MASK << 28U)
|
||||
#define IO_CALIB_STATE ((uint32_t)0xBU << 28U)
|
||||
#define RX_CAL_DONE ((uint32_t)BIT_MASK << 4U)
|
||||
#define CA_TRAIN_RL (((uint32_t)BIT_MASK << 5U) | ((uint32_t)BIT_MASK << 4U))
|
||||
#define WR_LVL_STATE (((uint32_t)NIBBLE_MASK) << 13U)
|
||||
#define GATE_LVL_ERROR_FIELDS (((uint32_t)BIT_MASK << 7U) | ((uint32_t)BIT_MASK << 6U))
|
||||
#define READ_LVL_ERROR_FIELDS ((((uint32_t)NIBBLE_MASK) << 28U) | (((uint32_t)BYTE_MASK) << 16U))
|
||||
#define DQ_LVL_STATUS (((uint32_t)BIT_MASK << 26U) | (((uint32_t)BYTE_MASK) << 18U))
|
||||
|
||||
#endif /* LPDDR4_PRIV_H */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,121 @@
|
||||
/* SPDX-License-Identifier: BSD-3-Clause */
|
||||
/**********************************************************************
|
||||
* Copyright (C) 2012-2019 Cadence Design Systems, Inc.
|
||||
**********************************************************************
|
||||
* WARNING: This file is auto-generated using api-generator utility.
|
||||
* api-generator: 12.02.13bb8d5
|
||||
* Do not edit it manually.
|
||||
**********************************************************************
|
||||
* Cadence Core Driver for LPDDR4.
|
||||
**********************************************************************
|
||||
*/
|
||||
#ifndef LPDDR4_STRUCTS_IF_H
|
||||
#define LPDDR4_STRUCTS_IF_H
|
||||
|
||||
#include <linux/types.h>
|
||||
#include "lpddr4_if.h"
|
||||
|
||||
/** @defgroup DataStructure Dynamic Data Structures
|
||||
* This section defines the data structures used by the driver to provide
|
||||
* hardware information, modification and dynamic operation of the driver.
|
||||
* These data structures are defined in the header file of the core driver
|
||||
* and utilized by the API.
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**********************************************************************
|
||||
* Structures and unions
|
||||
**********************************************************************/
|
||||
/**
|
||||
* Configuration of device.
|
||||
* Object of this type is used for probe and init functions.
|
||||
*/
|
||||
struct lpddr4_config_s
|
||||
{
|
||||
/** Base address of controller registers */
|
||||
struct lpddr4_ctlregs_s* ctlbase;
|
||||
/** Information/warning handler */
|
||||
lpddr4_infocallback infohandler;
|
||||
/** Controller interrupt handler */
|
||||
lpddr4_ctlcallback ctlinterrupthandler;
|
||||
/** PHY Independent Module interrupt handler */
|
||||
lpddr4_phyindepcallback phyindepinterrupthandler;
|
||||
};
|
||||
|
||||
/**
|
||||
* Structure contains private data for Core Driver that should not be used by
|
||||
* upper layers. This is not a part of API and manipulating of those data may cause
|
||||
* unpredictable behavior of Core Driver.
|
||||
*/
|
||||
struct lpddr4_privatedata_s
|
||||
{
|
||||
/** Base address of controller registers */
|
||||
struct lpddr4_ctlregs_s* ctlbase;
|
||||
/** Information/warning handler */
|
||||
lpddr4_infocallback infohandler;
|
||||
/** Controller interrupt handler */
|
||||
lpddr4_ctlcallback ctlinterrupthandler;
|
||||
/** PHY Independent Module interrupt handler */
|
||||
lpddr4_phyindepcallback phyindepinterrupthandler;
|
||||
};
|
||||
|
||||
/** Structure to contain debug information reported by the driver. */
|
||||
struct lpddr4_debuginfo_s
|
||||
{
|
||||
/** PLL Lock error. */
|
||||
bool pllerror;
|
||||
/** I/O calibration error. */
|
||||
bool iocaliberror;
|
||||
/** RX offset error. */
|
||||
bool rxoffseterror;
|
||||
/** CA training error. */
|
||||
bool catraingerror;
|
||||
/** Write levelling error. */
|
||||
bool wrlvlerror;
|
||||
/** Gate Level error. */
|
||||
bool gatelvlerror;
|
||||
/** Read Level error. */
|
||||
bool readlvlerror;
|
||||
/** Write DQ training error. */
|
||||
bool dqtrainingerror;
|
||||
};
|
||||
|
||||
/** Frequency Set Point mode register values */
|
||||
struct lpddr4_fspmoderegs_s
|
||||
{
|
||||
/** MR1 register data for the FSP. */
|
||||
uint8_t mr1data_fn[LPDDR4_MAX_CS];
|
||||
/** MR2 register data for the FSP. */
|
||||
uint8_t mr2data_fn[LPDDR4_MAX_CS];
|
||||
/** MR3 register data for the FSP. */
|
||||
uint8_t mr3data_fn[LPDDR4_MAX_CS];
|
||||
/** MR11 register data for the FSP. */
|
||||
uint8_t mr11data_fn[LPDDR4_MAX_CS];
|
||||
/** MR12 register data for the FSP. */
|
||||
uint8_t mr12data_fn[LPDDR4_MAX_CS];
|
||||
/** MR13 register data for the FSP. */
|
||||
uint8_t mr13data_fn[LPDDR4_MAX_CS];
|
||||
/** MR14 register data for the FSP. */
|
||||
uint8_t mr14data_fn[LPDDR4_MAX_CS];
|
||||
/** MR22 register data for the selected frequency. */
|
||||
uint8_t mr22data_fn[LPDDR4_MAX_CS];
|
||||
};
|
||||
|
||||
/** Structure to hold data set to initalise registers. */
|
||||
struct lpddr4_reginitdata_s
|
||||
{
|
||||
/** Register initialisation data for the Controller. */
|
||||
uint32_t denalictlreg[LPDDR4_CTL_REG_COUNT];
|
||||
/** Should be set to true, if the corresponding denaliCtlReg element has been updated. */
|
||||
bool updatectlreg[LPDDR4_CTL_REG_COUNT];
|
||||
/** Register initialisation data for PHY independent module. */
|
||||
uint32_t denaliphyindepreg[LPDDR4_PHY_INDEP_REG_COUNT];
|
||||
/** Should be set to true, if the corresponding denaliPhyIndepReg element has been updated. */
|
||||
bool updatephyindepreg[LPDDR4_PHY_INDEP_REG_COUNT];
|
||||
/** Register initialisation data for the PHY. */
|
||||
uint32_t denaliphyreg[LPDDR4_PHY_REG_COUNT];
|
||||
/** Should be set to true, if the corresponding denaliPhyReg element has been updated. */
|
||||
bool updatephyreg[LPDDR4_PHY_REG_COUNT];
|
||||
};
|
||||
|
||||
#endif /* LPDDR4_STRUCTS_IF_H */
|
||||
@@ -0,0 +1,7 @@
|
||||
#
|
||||
# Copyright (c) 2018 MediaTek Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
#
|
||||
|
||||
obj-$(CONFIG_TARGET_MT7629) = ddr3-mt7629.o
|
||||
@@ -0,0 +1,766 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* MediaTek DDR3 driver for MT7629 SoC
|
||||
*
|
||||
* Copyright (C) 2018 MediaTek Inc.
|
||||
* Author: Wu Zou <wu.zou@mediatek.com>
|
||||
* Ryder Lee <ryder.lee@mediatek.com>
|
||||
*/
|
||||
|
||||
#include <clk.h>
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <ram.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
/* EMI */
|
||||
#define EMI_CONA 0x000
|
||||
#define EMI_CONF 0x028
|
||||
#define EMI_CONM 0x060
|
||||
|
||||
/* DDR PHY */
|
||||
#define DDRPHY_PLL1 0x0000
|
||||
#define DDRPHY_PLL2 0x0004
|
||||
#define DDRPHY_PLL3 0x0008
|
||||
#define DDRPHY_PLL4 0x000c
|
||||
#define DDRPHY_PLL5 0x0010
|
||||
#define DDRPHY_PLL7 0x0018
|
||||
#define DDRPHY_B0_DLL_ARPI0 0x0080
|
||||
#define DDRPHY_B0_DLL_ARPI1 0x0084
|
||||
#define DDRPHY_B0_DLL_ARPI2 0x0088
|
||||
#define DDRPHY_B0_DLL_ARPI3 0x008c
|
||||
#define DDRPHY_B0_DLL_ARPI4 0x0090
|
||||
#define DDRPHY_B0_DLL_ARPI5 0x0094
|
||||
#define DDRPHY_B0_DQ2 0x00a0
|
||||
#define DDRPHY_B0_DQ3 0x00a4
|
||||
#define DDRPHY_B0_DQ4 0x00a8
|
||||
#define DDRPHY_B0_DQ5 0x00ac
|
||||
#define DDRPHY_B0_DQ6 0x00b0
|
||||
#define DDRPHY_B0_DQ7 0x00b4
|
||||
#define DDRPHY_B0_DQ8 0x00b8
|
||||
#define DDRPHY_B1_DLL_ARPI0 0x0100
|
||||
#define DDRPHY_B1_DLL_ARPI1 0x0104
|
||||
#define DDRPHY_B1_DLL_ARPI2 0x0108
|
||||
#define DDRPHY_B1_DLL_ARPI3 0x010c
|
||||
#define DDRPHY_B1_DLL_ARPI4 0x0110
|
||||
#define DDRPHY_B1_DLL_ARPI5 0x0114
|
||||
#define DDRPHY_B1_DQ2 0x0120
|
||||
#define DDRPHY_B1_DQ3 0x0124
|
||||
#define DDRPHY_B1_DQ4 0x0128
|
||||
#define DDRPHY_B1_DQ5 0x012c
|
||||
#define DDRPHY_B1_DQ6 0x0130
|
||||
#define DDRPHY_B1_DQ7 0x0134
|
||||
#define DDRPHY_B1_DQ8 0x0138
|
||||
#define DDRPHY_CA_DLL_ARPI0 0x0180
|
||||
#define DDRPHY_CA_DLL_ARPI1 0x0184
|
||||
#define DDRPHY_CA_DLL_ARPI2 0x0188
|
||||
#define DDRPHY_CA_DLL_ARPI3 0x018c
|
||||
#define DDRPHY_CA_DLL_ARPI4 0x0190
|
||||
#define DDRPHY_CA_DLL_ARPI5 0x0194
|
||||
#define DDRPHY_CA_CMD2 0x01a0
|
||||
#define DDRPHY_CA_CMD3 0x01a4
|
||||
#define DDRPHY_CA_CMD5 0x01ac
|
||||
#define DDRPHY_CA_CMD6 0x01b0
|
||||
#define DDRPHY_CA_CMD7 0x01b4
|
||||
#define DDRPHY_CA_CMD8 0x01b8
|
||||
#define DDRPHY_MISC_VREF_CTRL 0x0264
|
||||
#define DDRPHY_MISC_IMP_CTRL0 0x0268
|
||||
#define DDRPHY_MISC_IMP_CTRL1 0x026c
|
||||
#define DDRPHY_MISC_SHU_OPT 0x0270
|
||||
#define DDRPHY_MISC_SPM_CTRL0 0x0274
|
||||
#define DDRPHY_MISC_SPM_CTRL1 0x0278
|
||||
#define DDRPHY_MISC_SPM_CTRL2 0x027c
|
||||
#define DDRPHY_MISC_CG_CTRL0 0x0284
|
||||
#define DDRPHY_MISC_CG_CTRL1 0x0288
|
||||
#define DDRPHY_MISC_CG_CTRL2 0x028c
|
||||
#define DDRPHY_MISC_CG_CTRL4 0x0294
|
||||
#define DDRPHY_MISC_CTRL0 0x029c
|
||||
#define DDRPHY_MISC_CTRL1 0x02a0
|
||||
#define DDRPHY_MISC_CTRL3 0x02a8
|
||||
#define DDRPHY_MISC_RXDVS1 0x05e4
|
||||
#define DDRPHY_SHU1_B0_DQ4 0x0c10
|
||||
#define DDRPHY_SHU1_B0_DQ5 0x0c14
|
||||
#define DDRPHY_SHU1_B0_DQ6 0x0c18
|
||||
#define DDRPHY_SHU1_B0_DQ7 0x0c1c
|
||||
#define DDRPHY_SHU1_B1_DQ4 0x0c90
|
||||
#define DDRPHY_SHU1_B1_DQ5 0x0c94
|
||||
#define DDRPHY_SHU1_B1_DQ6 0x0c98
|
||||
#define DDRPHY_SHU1_B1_DQ7 0x0c9c
|
||||
#define DDRPHY_SHU1_CA_CMD2 0x0d08
|
||||
#define DDRPHY_SHU1_CA_CMD4 0x0d10
|
||||
#define DDRPHY_SHU1_CA_CMD5 0x0d14
|
||||
#define DDRPHY_SHU1_CA_CMD6 0x0d18
|
||||
#define DDRPHY_SHU1_CA_CMD7 0x0d1c
|
||||
#define DDRPHY_SHU1_PLL0 0x0d80
|
||||
#define DDRPHY_SHU1_PLL1 0x0d84
|
||||
#define DDRPHY_SHU1_PLL4 0x0d90
|
||||
#define DDRPHY_SHU1_PLL5 0x0d94
|
||||
#define DDRPHY_SHU1_PLL6 0x0d98
|
||||
#define DDRPHY_SHU1_PLL7 0x0d9C
|
||||
#define DDRPHY_SHU1_PLL8 0x0da0
|
||||
#define DDRPHY_SHU1_PLL9 0x0da4
|
||||
#define DDRPHY_SHU1_PLL10 0x0da8
|
||||
#define DDRPHY_SHU1_PLL11 0x0dac
|
||||
#define DDRPHY_SHU1_R0_B0_DQ2 0x0e08
|
||||
#define DDRPHY_SHU1_R0_B0_DQ3 0x0e0c
|
||||
#define DDRPHY_SHU1_R0_B0_DQ4 0x0e10
|
||||
#define DDRPHY_SHU1_R0_B0_DQ5 0x0e14
|
||||
#define DDRPHY_SHU1_R0_B0_DQ6 0x0e18
|
||||
#define DDRPHY_SHU1_R0_B0_DQ7 0x0e1c
|
||||
#define DDRPHY_SHU1_R0_B1_DQ2 0x0e58
|
||||
#define DDRPHY_SHU1_R0_B1_DQ3 0x0e5c
|
||||
#define DDRPHY_SHU1_R0_B1_DQ4 0x0e60
|
||||
#define DDRPHY_SHU1_R0_B1_DQ5 0x0e64
|
||||
#define DDRPHY_SHU1_R0_B1_DQ6 0x0e68
|
||||
#define DDRPHY_SHU1_R0_B1_DQ7 0x0e6c
|
||||
#define DDRPHY_SHU1_R0_CA_CMD9 0x0ec4
|
||||
#define DDRPHY_SHU1_R1_B0_DQ2 0x0f08
|
||||
#define DDRPHY_SHU1_R1_B0_DQ3 0x0f0c
|
||||
#define DDRPHY_SHU1_R1_B0_DQ4 0x0f10
|
||||
#define DDRPHY_SHU1_R1_B0_DQ5 0x0f14
|
||||
#define DDRPHY_SHU1_R1_B0_DQ6 0x0f18
|
||||
#define DDRPHY_SHU1_R1_B0_DQ7 0x0f1c
|
||||
#define DDRPHY_SHU1_R1_B1_DQ2 0x0f58
|
||||
#define DDRPHY_SHU1_R1_B1_DQ3 0x0f5c
|
||||
#define DDRPHY_SHU1_R1_B1_DQ4 0x0f60
|
||||
#define DDRPHY_SHU1_R1_B1_DQ5 0x0f64
|
||||
#define DDRPHY_SHU1_R1_B1_DQ6 0x0f68
|
||||
#define DDRPHY_SHU1_R1_B1_DQ7 0x0f6c
|
||||
#define DDRPHY_SHU1_R1_CA_CMD9 0x0fc4
|
||||
|
||||
/* DRAMC */
|
||||
#define DRAMC_DDRCONF0 0x0000
|
||||
#define DRAMC_DRAMCTRL 0x0004
|
||||
#define DRAMC_MISCTL0 0x0008
|
||||
#define DRAMC_PERFCTL0 0x000c
|
||||
#define DRAMC_ARBCTL 0x0010
|
||||
#define DRAMC_RSTMASK 0x001c
|
||||
#define DRAMC_PADCTRL 0x0020
|
||||
#define DRAMC_CKECTRL 0x0024
|
||||
#define DRAMC_RKCFG 0x0034
|
||||
#define DRAMC_DRAMC_PD_CTRL 0x0038
|
||||
#define DRAMC_CLKAR 0x003c
|
||||
#define DRAMC_CLKCTRL 0x0040
|
||||
#define DRAMC_SREFCTRL 0x0048
|
||||
#define DRAMC_REFCTRL0 0x004c
|
||||
#define DRAMC_REFCTRL1 0x0050
|
||||
#define DRAMC_REFRATRE_FILTER 0x0054
|
||||
#define DRAMC_ZQCS 0x0058
|
||||
#define DRAMC_MRS 0x005c
|
||||
#define DRAMC_SPCMD 0x0060
|
||||
#define DRAMC_SPCMDCTRL 0x0064
|
||||
#define DRAMC_HW_MRR_FUN 0x0074
|
||||
#define DRAMC_TEST2_1 0x0094
|
||||
#define DRAMC_TEST2_2 0x0098
|
||||
#define DRAMC_TEST2_3 0x009c
|
||||
#define DRAMC_TEST2_4 0x00a0
|
||||
#define DRAMC_CATRAINING1 0x00b0
|
||||
#define DRAMC_DUMMY_RD 0x00d0
|
||||
#define DRAMC_SHUCTRL 0x00d4
|
||||
#define DRAMC_SHUCTRL2 0x00dc
|
||||
#define DRAMC_STBCAL 0x0200
|
||||
#define DRAMC_STBCAL1 0x0204
|
||||
#define DRAMC_EYESCAN 0x020c
|
||||
#define DRAMC_DVFSDLL 0x0210
|
||||
#define DRAMC_SHU_ACTIM0 0x0800
|
||||
#define DRAMC_SHU_ACTIM1 0x0804
|
||||
#define DRAMC_SHU_ACTIM2 0x0808
|
||||
#define DRAMC_SHU_ACTIM3 0x080c
|
||||
#define DRAMC_SHU_ACTIM4 0x0810
|
||||
#define DRAMC_SHU_ACTIM5 0x0814
|
||||
#define DRAMC_SHU_ACTIM_XRT 0x081c
|
||||
#define DRAMC_SHU_AC_TIME_05T 0x0820
|
||||
#define DRAMC_SHU_CONF0 0x0840
|
||||
#define DRAMC_SHU_CONF1 0x0844
|
||||
#define DRAMC_SHU_CONF2 0x0848
|
||||
#define DRAMC_SHU_CONF3 0x084c
|
||||
#define DRAMC_SHU_RANKCTL 0x0858
|
||||
#define DRAMC_SHU_CKECTRL 0x085c
|
||||
#define DRAMC_SHU_ODTCTRL 0x0860
|
||||
#define DRAMC_SHU_PIPE 0x0878
|
||||
#define DRAMC_SHU_SELPH_CA1 0x0880
|
||||
#define DRAMC_SHU_SELPH_CA2 0x0884
|
||||
#define DRAMC_SHU_SELPH_CA3 0x0888
|
||||
#define DRAMC_SHU_SELPH_CA4 0x088c
|
||||
#define DRAMC_SHU_SELPH_CA5 0x0890
|
||||
#define DRAMC_SHU_SELPH_CA6 0x0894
|
||||
#define DRAMC_SHU_SELPH_CA7 0x0898
|
||||
#define DRAMC_SHU_SELPH_CA8 0x089c
|
||||
#define DRAMC_SHU_SELPH_DQS0 0x08a0
|
||||
#define DRAMC_SHU_SELPH_DQS1 0x08a4
|
||||
#define DRAMC_SHU1_DRVING1 0x08a8
|
||||
#define DRAMC_SHU1_DRVING2 0x08ac
|
||||
#define DRAMC_SHU1_WODT 0x08c0
|
||||
#define DRAMC_SHU_SCINTV 0x08c8
|
||||
#define DRAMC_SHURK0_DQSCTL 0x0a00
|
||||
#define DRAMC_SHURK0_DQSIEN 0x0a04
|
||||
#define DRAMC_SHURK0_SELPH_ODTEN0 0x0a1c
|
||||
#define DRAMC_SHURK0_SELPH_ODTEN1 0x0a20
|
||||
#define DRAMC_SHURK0_SELPH_DQSG0 0x0a24
|
||||
#define DRAMC_SHURK0_SELPH_DQSG1 0x0a28
|
||||
#define DRAMC_SHURK0_SELPH_DQ0 0x0a2c
|
||||
#define DRAMC_SHURK0_SELPH_DQ1 0x0a30
|
||||
#define DRAMC_SHURK0_SELPH_DQ2 0x0a34
|
||||
#define DRAMC_SHURK0_SELPH_DQ3 0x0a38
|
||||
#define DRAMC_SHURK1_DQSCTL 0x0b00
|
||||
#define DRAMC_SHURK1_SELPH_ODTEN0 0x0b1c
|
||||
#define DRAMC_SHURK1_SELPH_ODTEN1 0x0b20
|
||||
#define DRAMC_SHURK1_SELPH_DQSG0 0x0b24
|
||||
#define DRAMC_SHURK1_SELPH_DQSG1 0x0b28
|
||||
#define DRAMC_SHURK1_SELPH_DQ0 0x0b2c
|
||||
#define DRAMC_SHURK1_SELPH_DQ1 0x0b30
|
||||
#define DRAMC_SHURK1_SELPH_DQ2 0x0b34
|
||||
#define DRAMC_SHURK1_SELPH_DQ3 0x0b38
|
||||
#define DRAMC_SHURK2_SELPH_ODTEN0 0x0c1c
|
||||
#define DRAMC_SHURK2_SELPH_ODTEN1 0x0c20
|
||||
#define DRAMC_SHU_DQSG_RETRY 0x0c54
|
||||
|
||||
#define EMI_COL_ADDR_MASK GENMASK(13, 12)
|
||||
#define EMI_COL_ADDR_SHIFT 12
|
||||
#define WALKING_PATTERN 0x12345678
|
||||
#define WALKING_STEP 0x4000000
|
||||
|
||||
struct mtk_ddr3_priv {
|
||||
fdt_addr_t emi;
|
||||
fdt_addr_t ddrphy;
|
||||
fdt_addr_t dramc_ao;
|
||||
struct clk phy;
|
||||
struct clk phy_mux;
|
||||
struct clk mem;
|
||||
struct clk mem_mux;
|
||||
};
|
||||
|
||||
#ifdef CONFIG_SPL_BUILD
|
||||
static int mtk_ddr3_rank_size_detect(struct udevice *dev)
|
||||
{
|
||||
struct mtk_ddr3_priv *priv = dev_get_priv(dev);
|
||||
int step;
|
||||
u32 start, test;
|
||||
|
||||
/* To detect size, we have to make sure it's single rank
|
||||
* and it has maximum addressing region
|
||||
*/
|
||||
|
||||
writel(WALKING_PATTERN, CONFIG_SYS_SDRAM_BASE);
|
||||
|
||||
if (readl(CONFIG_SYS_SDRAM_BASE) != WALKING_PATTERN)
|
||||
return -EINVAL;
|
||||
|
||||
for (step = 0; step < 5; step++) {
|
||||
writel(~WALKING_PATTERN, CONFIG_SYS_SDRAM_BASE +
|
||||
(WALKING_STEP << step));
|
||||
|
||||
start = readl(CONFIG_SYS_SDRAM_BASE);
|
||||
test = readl(CONFIG_SYS_SDRAM_BASE + (WALKING_STEP << step));
|
||||
if ((test != ~WALKING_PATTERN) || test == start)
|
||||
break;
|
||||
}
|
||||
|
||||
step = step ? step - 1 : 3;
|
||||
clrsetbits_le32(priv->emi + EMI_CONA, EMI_COL_ADDR_MASK,
|
||||
step << EMI_COL_ADDR_SHIFT);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mtk_ddr3_init(struct udevice *dev)
|
||||
{
|
||||
struct mtk_ddr3_priv *priv = dev_get_priv(dev);
|
||||
int ret;
|
||||
|
||||
ret = clk_set_parent(&priv->phy, &priv->phy_mux);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* EMI Setting */
|
||||
writel(0x00003010, priv->emi + EMI_CONA);
|
||||
writel(0x00000000, priv->emi + EMI_CONF);
|
||||
writel(0x000006b8, priv->emi + EMI_CONM);
|
||||
/* DQS */
|
||||
writel(0x20c00, priv->dramc_ao + DRAMC_SHU1_DRVING1);
|
||||
/* Clock */
|
||||
writel(0x8320c83, priv->dramc_ao + DRAMC_SHU1_DRVING2);
|
||||
|
||||
/* DDRPHY setting */
|
||||
writel(0x2201, priv->dramc_ao + DRAMC_DRAMCTRL);
|
||||
writel(0x3000000c, priv->dramc_ao + DRAMC_CLKCTRL);
|
||||
writel(0xe08, priv->ddrphy + DDRPHY_CA_CMD5);
|
||||
writel(0x60e, priv->ddrphy + DDRPHY_SHU1_CA_CMD5);
|
||||
writel(0x0, priv->ddrphy + DDRPHY_MISC_SPM_CTRL1);
|
||||
writel(0xffffffff, priv->ddrphy + DDRPHY_MISC_SPM_CTRL0);
|
||||
writel(0xffffffff, priv->ddrphy + DDRPHY_MISC_SPM_CTRL2);
|
||||
writel(0x6003bf, priv->ddrphy + DDRPHY_MISC_CG_CTRL2);
|
||||
writel(0x13300000, priv->ddrphy + DDRPHY_MISC_CG_CTRL4);
|
||||
|
||||
writel(0x1, priv->ddrphy + DDRPHY_SHU1_CA_CMD7);
|
||||
writel(0x21, priv->ddrphy + DDRPHY_SHU1_B0_DQ7);
|
||||
writel(0x1, priv->ddrphy + DDRPHY_SHU1_B1_DQ7);
|
||||
writel(0xfff0, priv->ddrphy + DDRPHY_CA_CMD2);
|
||||
writel(0x0, priv->ddrphy + DDRPHY_B0_DQ2);
|
||||
writel(0x0, priv->ddrphy + DDRPHY_B1_DQ2);
|
||||
writel(0x7, priv->ddrphy + DDRPHY_MISC_RXDVS1);
|
||||
writel(0x10, priv->ddrphy + DDRPHY_PLL3);
|
||||
writel(0x8e8e0000, priv->ddrphy + DDRPHY_MISC_VREF_CTRL);
|
||||
writel(0x2e0040, priv->ddrphy + DDRPHY_MISC_IMP_CTRL0);
|
||||
writel(0x50060e, priv->ddrphy + DDRPHY_SHU1_B0_DQ5);
|
||||
writel(0x50060e, priv->ddrphy + DDRPHY_SHU1_B1_DQ5);
|
||||
udelay(1);
|
||||
|
||||
writel(0x10, priv->ddrphy + DDRPHY_B0_DQ3);
|
||||
writel(0x10, priv->ddrphy + DDRPHY_B1_DQ3);
|
||||
writel(0x3f600, priv->ddrphy + DDRPHY_MISC_CG_CTRL1);
|
||||
writel(0x1010, priv->ddrphy + DDRPHY_B0_DQ4);
|
||||
writel(0x1110e0e, priv->ddrphy + DDRPHY_B0_DQ5);
|
||||
writel(0x10c10d0, priv->ddrphy + DDRPHY_B0_DQ6);
|
||||
writel(0x3110e0e, priv->ddrphy + DDRPHY_B0_DQ5);
|
||||
writel(0x1010, priv->ddrphy + DDRPHY_B1_DQ4);
|
||||
writel(0x1110e0e, priv->ddrphy + DDRPHY_B1_DQ5);
|
||||
writel(0x10c10d0, priv->ddrphy + DDRPHY_B1_DQ6);
|
||||
writel(0x3110e0e, priv->ddrphy + DDRPHY_B1_DQ5);
|
||||
writel(0x7fffffc, priv->ddrphy + DDRPHY_CA_CMD3);
|
||||
writel(0xc0010, priv->ddrphy + DDRPHY_CA_CMD6);
|
||||
writel(0x101, priv->ddrphy + DDRPHY_SHU1_CA_CMD2);
|
||||
writel(0x41e, priv->ddrphy + DDRPHY_B0_DQ3);
|
||||
writel(0x41e, priv->ddrphy + DDRPHY_B1_DQ3);
|
||||
writel(0x180101, priv->ddrphy + DDRPHY_CA_CMD8);
|
||||
writel(0x0, priv->ddrphy + DDRPHY_MISC_IMP_CTRL1);
|
||||
writel(0x11400000, priv->ddrphy + DDRPHY_MISC_CG_CTRL4);
|
||||
writel(0xfff0f0f0, priv->ddrphy + DDRPHY_MISC_SHU_OPT);
|
||||
writel(0x1f, priv->ddrphy + DDRPHY_MISC_CG_CTRL0);
|
||||
|
||||
writel(0x0, priv->ddrphy + DDRPHY_SHU1_CA_CMD6);
|
||||
writel(0x0, priv->ddrphy + DDRPHY_SHU1_B0_DQ6);
|
||||
writel(0x0, priv->ddrphy + DDRPHY_SHU1_B1_DQ6);
|
||||
writel(0x40000, priv->ddrphy + DDRPHY_PLL4);
|
||||
writel(0x0, priv->ddrphy + DDRPHY_PLL1);
|
||||
writel(0x0, priv->ddrphy + DDRPHY_PLL2);
|
||||
writel(0x666008, priv->ddrphy + DDRPHY_CA_DLL_ARPI5);
|
||||
writel(0x80666008, priv->ddrphy + DDRPHY_B0_DLL_ARPI5);
|
||||
writel(0x80666008, priv->ddrphy + DDRPHY_B1_DLL_ARPI5);
|
||||
writel(0x0, priv->ddrphy + DDRPHY_CA_DLL_ARPI0);
|
||||
writel(0x0, priv->ddrphy + DDRPHY_B0_DLL_ARPI0);
|
||||
writel(0x0, priv->ddrphy + DDRPHY_B1_DLL_ARPI0);
|
||||
writel(0x400, priv->ddrphy + DDRPHY_CA_DLL_ARPI2);
|
||||
writel(0x20400, priv->ddrphy + DDRPHY_B0_DLL_ARPI2);
|
||||
writel(0x20400, priv->ddrphy + DDRPHY_B1_DLL_ARPI2);
|
||||
writel(0x0, priv->ddrphy + DDRPHY_SHU1_PLL9);
|
||||
writel(0x0, priv->ddrphy + DDRPHY_SHU1_PLL11);
|
||||
writel(0xf7f, priv->ddrphy + DDRPHY_SHU1_PLL0);
|
||||
writel(0x40000, priv->ddrphy + DDRPHY_SHU1_PLL8);
|
||||
writel(0x40000, priv->ddrphy + DDRPHY_SHU1_PLL10);
|
||||
writel(0xe57800fe, priv->ddrphy + DDRPHY_SHU1_PLL4);
|
||||
writel(0xe57800fe, priv->ddrphy + DDRPHY_SHU1_PLL6);
|
||||
|
||||
writel(0xB5000000, priv->ddrphy + DDRPHY_SHU1_PLL5);
|
||||
writel(0xB5000000, priv->ddrphy + DDRPHY_SHU1_PLL7);
|
||||
|
||||
writel(0x14d0002, priv->ddrphy + DDRPHY_PLL5);
|
||||
writel(0x14d0002, priv->ddrphy + DDRPHY_PLL7);
|
||||
writel(0x80040000, priv->ddrphy + DDRPHY_SHU1_PLL8);
|
||||
writel(0x80040000, priv->ddrphy + DDRPHY_SHU1_PLL10);
|
||||
writel(0xf, priv->ddrphy + DDRPHY_SHU1_PLL1);
|
||||
writel(0x4, priv->ddrphy + DDRPHY_CA_DLL_ARPI0);
|
||||
writel(0x1, priv->ddrphy + DDRPHY_B0_DLL_ARPI0);
|
||||
writel(0x1, priv->ddrphy + DDRPHY_B1_DLL_ARPI0);
|
||||
writel(0x698600, priv->ddrphy + DDRPHY_CA_DLL_ARPI5);
|
||||
writel(0xc0778600, priv->ddrphy + DDRPHY_B0_DLL_ARPI5);
|
||||
writel(0xc0778600, priv->ddrphy + DDRPHY_B1_DLL_ARPI5);
|
||||
writel(0x0, priv->ddrphy + DDRPHY_CA_DLL_ARPI4);
|
||||
writel(0x0, priv->ddrphy + DDRPHY_B0_DLL_ARPI4);
|
||||
writel(0x0, priv->ddrphy + DDRPHY_B1_DLL_ARPI4);
|
||||
writel(0x2ba800, priv->ddrphy + DDRPHY_CA_DLL_ARPI1);
|
||||
writel(0x2ae806, priv->ddrphy + DDRPHY_B0_DLL_ARPI1);
|
||||
writel(0xae806, priv->ddrphy + DDRPHY_B1_DLL_ARPI1);
|
||||
writel(0xba000, priv->ddrphy + DDRPHY_CA_DLL_ARPI3);
|
||||
writel(0x2e800, priv->ddrphy + DDRPHY_B0_DLL_ARPI3);
|
||||
writel(0x2e800, priv->ddrphy + DDRPHY_B1_DLL_ARPI3);
|
||||
writel(0x0, priv->ddrphy + DDRPHY_SHU1_CA_CMD4);
|
||||
writel(0x0, priv->ddrphy + DDRPHY_SHU1_B0_DQ4);
|
||||
writel(0x0, priv->ddrphy + DDRPHY_SHU1_B1_DQ4);
|
||||
writel(0x4, priv->ddrphy + DDRPHY_CA_DLL_ARPI0);
|
||||
writel(0x1, priv->ddrphy + DDRPHY_B0_DLL_ARPI0);
|
||||
writel(0x1, priv->ddrphy + DDRPHY_B1_DLL_ARPI0);
|
||||
writel(0x32cf0000, priv->ddrphy + DDRPHY_SHU1_CA_CMD6);
|
||||
writel(0x32cd0000, priv->ddrphy + DDRPHY_SHU1_B0_DQ6);
|
||||
writel(0x32cd0000, priv->ddrphy + DDRPHY_SHU1_B1_DQ6);
|
||||
writel(0x80010000, priv->ddrphy + DDRPHY_PLL1);
|
||||
writel(0x80000000, priv->ddrphy + DDRPHY_PLL2);
|
||||
udelay(100);
|
||||
|
||||
writel(0xc, priv->ddrphy + DDRPHY_CA_DLL_ARPI0);
|
||||
writel(0x9, priv->ddrphy + DDRPHY_B0_DLL_ARPI0);
|
||||
writel(0x9, priv->ddrphy + DDRPHY_B1_DLL_ARPI0);
|
||||
writel(0xd0000, priv->ddrphy + DDRPHY_PLL4);
|
||||
udelay(1);
|
||||
|
||||
writel(0x82, priv->ddrphy + DDRPHY_MISC_CTRL1);
|
||||
writel(0x2, priv->dramc_ao + DRAMC_DDRCONF0);
|
||||
writel(0x3acf0000, priv->ddrphy + DDRPHY_SHU1_CA_CMD6);
|
||||
writel(0x3acd0000, priv->ddrphy + DDRPHY_SHU1_B0_DQ6);
|
||||
writel(0x3acd0000, priv->ddrphy + DDRPHY_SHU1_B1_DQ6);
|
||||
udelay(1);
|
||||
|
||||
writel(0x0, priv->ddrphy + DDRPHY_CA_DLL_ARPI2);
|
||||
writel(0x0, priv->ddrphy + DDRPHY_B0_DLL_ARPI2);
|
||||
writel(0x0, priv->ddrphy + DDRPHY_B1_DLL_ARPI2);
|
||||
writel(0x80, priv->ddrphy + DDRPHY_MISC_CTRL1);
|
||||
writel(0x0, priv->dramc_ao + DRAMC_DDRCONF0);
|
||||
writel(0x80000000, priv->ddrphy + DDRPHY_PLL1);
|
||||
udelay(1);
|
||||
|
||||
writel(0x698e00, priv->ddrphy + DDRPHY_CA_DLL_ARPI5);
|
||||
udelay(1);
|
||||
|
||||
writel(0xc0778e00, priv->ddrphy + DDRPHY_B0_DLL_ARPI5);
|
||||
udelay(1);
|
||||
|
||||
writel(0xc0778e00, priv->ddrphy + DDRPHY_B1_DLL_ARPI5);
|
||||
udelay(1);
|
||||
|
||||
ret = clk_set_parent(&priv->mem, &priv->mem_mux);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* DDR PHY PLL setting */
|
||||
writel(0x51e, priv->ddrphy + DDRPHY_B0_DQ3);
|
||||
writel(0x51e, priv->ddrphy + DDRPHY_B1_DQ3);
|
||||
writel(0x8100008c, priv->ddrphy + DDRPHY_MISC_CTRL1);
|
||||
writel(0x80101, priv->ddrphy + DDRPHY_CA_CMD8);
|
||||
writel(0x100, priv->ddrphy + DDRPHY_CA_CMD7);
|
||||
writel(0x0, priv->ddrphy + DDRPHY_CA_CMD7);
|
||||
writel(0x0, priv->ddrphy + DDRPHY_B0_DQ7);
|
||||
writel(0x0, priv->ddrphy + DDRPHY_B1_DQ7);
|
||||
writel(0x51e, priv->ddrphy + DDRPHY_B0_DQ3);
|
||||
writel(0xff051e, priv->ddrphy + DDRPHY_B1_DQ3);
|
||||
writel(0x0, priv->ddrphy + DDRPHY_B0_DQ2);
|
||||
writel(0x1ff, priv->ddrphy + DDRPHY_B1_DQ2);
|
||||
|
||||
/* Update initial setting */
|
||||
writel(0x5fc, priv->ddrphy + DDRPHY_B0_DQ3);
|
||||
writel(0xff05fc, priv->ddrphy + DDRPHY_B1_DQ3);
|
||||
writel(0x10c12d9, priv->ddrphy + DDRPHY_B0_DQ6);
|
||||
writel(0x10c12d9, priv->ddrphy + DDRPHY_B1_DQ6);
|
||||
writel(0xc0259, priv->ddrphy + DDRPHY_CA_CMD6);
|
||||
writel(0x4000, priv->ddrphy + DDRPHY_B0_DQ2);
|
||||
writel(0x41ff, priv->ddrphy + DDRPHY_B1_DQ2);
|
||||
writel(0x0, priv->ddrphy + DDRPHY_B0_DQ8);
|
||||
writel(0x100, priv->ddrphy + DDRPHY_B1_DQ8);
|
||||
writel(0x3110e0e, priv->ddrphy + DDRPHY_B0_DQ5);
|
||||
writel(0x3110e0e, priv->ddrphy + DDRPHY_B1_DQ5);
|
||||
writel(0x51060e, priv->ddrphy + DDRPHY_SHU1_B0_DQ5);
|
||||
writel(0x51060e, priv->ddrphy + DDRPHY_SHU1_B1_DQ5);
|
||||
writel(0x39eff6, priv->dramc_ao + DRAMC_SHU_SCINTV);
|
||||
writel(0x204ffff, priv->dramc_ao + DRAMC_CLKAR);
|
||||
writel(0x31b1f1cf, priv->dramc_ao + DRAMC_SPCMDCTRL);
|
||||
writel(0x0, priv->dramc_ao + DRAMC_PERFCTL0);
|
||||
writel(0x80000, priv->dramc_ao + DRAMC_PERFCTL0);
|
||||
|
||||
/* Dramc setting PC3 */
|
||||
writel(0x65714001, priv->dramc_ao + DRAMC_REFCTRL0);
|
||||
|
||||
writel(0x11351131, priv->ddrphy + DDRPHY_MISC_CTRL3);
|
||||
writel(0x200600, priv->dramc_ao + DRAMC_SHU_DQSG_RETRY);
|
||||
writel(0x101d007, priv->dramc_ao + DRAMC_SHUCTRL2);
|
||||
writel(0xe090601, priv->dramc_ao + DRAMC_DVFSDLL);
|
||||
writel(0x20003000, priv->dramc_ao + DRAMC_DDRCONF0);
|
||||
writel(0x3900020f, priv->ddrphy + DDRPHY_MISC_CTRL0);
|
||||
writel(0xa20810bf, priv->dramc_ao + DRAMC_SHU_CONF0);
|
||||
writel(0x30050, priv->dramc_ao + DRAMC_SHU_ODTCTRL);
|
||||
writel(0x25712000, priv->dramc_ao + DRAMC_REFCTRL0);
|
||||
writel(0xb0100000, priv->dramc_ao + DRAMC_STBCAL);
|
||||
writel(0x8000000, priv->dramc_ao + DRAMC_SREFCTRL);
|
||||
writel(0xc0000000, priv->dramc_ao + DRAMC_SHU_PIPE);
|
||||
writel(0x731004, priv->dramc_ao + DRAMC_RKCFG);
|
||||
writel(0x8007320f, priv->dramc_ao + DRAMC_SHU_CONF2);
|
||||
writel(0x2a7c0, priv->dramc_ao + DRAMC_SHU_SCINTV);
|
||||
writel(0xc110, priv->dramc_ao + DRAMC_SHUCTRL);
|
||||
writel(0x30000700, priv->dramc_ao + DRAMC_REFCTRL1);
|
||||
writel(0x6543b321, priv->dramc_ao + DRAMC_REFRATRE_FILTER);
|
||||
|
||||
/* Update PCDDR3 default setting */
|
||||
writel(0x0, priv->dramc_ao + DRAMC_SHU_SELPH_CA1);
|
||||
writel(0x0, priv->dramc_ao + DRAMC_SHU_SELPH_CA2);
|
||||
writel(0x0, priv->dramc_ao + DRAMC_SHU_SELPH_CA3);
|
||||
writel(0x0, priv->dramc_ao + DRAMC_SHU_SELPH_CA4);
|
||||
writel(0x10000111, priv->dramc_ao + DRAMC_SHU_SELPH_CA5);
|
||||
writel(0x1000000, priv->dramc_ao + DRAMC_SHU_SELPH_CA6);
|
||||
writel(0x0, priv->dramc_ao + DRAMC_SHU_SELPH_CA7);
|
||||
writel(0x0, priv->dramc_ao + DRAMC_SHU_SELPH_CA8);
|
||||
writel(0x0, priv->ddrphy + DDRPHY_SHU1_R0_CA_CMD9);
|
||||
writel(0x0, priv->ddrphy + DDRPHY_SHU1_R1_CA_CMD9);
|
||||
writel(0x11112222, priv->dramc_ao + DRAMC_SHU_SELPH_DQS0);
|
||||
writel(0x33331111, priv->dramc_ao + DRAMC_SHU_SELPH_DQS1);
|
||||
writel(0x11112222, priv->dramc_ao + DRAMC_SHURK0_SELPH_DQ0);
|
||||
writel(0x11112222, priv->dramc_ao + DRAMC_SHURK0_SELPH_DQ1);
|
||||
writel(0x33331111, priv->dramc_ao + DRAMC_SHURK0_SELPH_DQ2);
|
||||
writel(0x33331111, priv->dramc_ao + DRAMC_SHURK0_SELPH_DQ3);
|
||||
writel(0x11112222, priv->dramc_ao + DRAMC_SHURK1_SELPH_DQ0);
|
||||
writel(0x11112222, priv->dramc_ao + DRAMC_SHURK1_SELPH_DQ1);
|
||||
writel(0x33331111, priv->dramc_ao + DRAMC_SHURK1_SELPH_DQ2);
|
||||
writel(0x33331111, priv->dramc_ao + DRAMC_SHURK1_SELPH_DQ3);
|
||||
writel(0xf0f00, priv->ddrphy + DDRPHY_SHU1_R0_B0_DQ7);
|
||||
writel(0xf0f00, priv->ddrphy + DDRPHY_SHU1_R1_B0_DQ7);
|
||||
writel(0xf0f00, priv->ddrphy + DDRPHY_SHU1_R0_B1_DQ7);
|
||||
writel(0xf0f00, priv->ddrphy + DDRPHY_SHU1_R1_B1_DQ7);
|
||||
writel(0x0, priv->dramc_ao + DRAMC_SHURK0_SELPH_ODTEN0);
|
||||
writel(0x0, priv->dramc_ao + DRAMC_SHURK0_SELPH_ODTEN1);
|
||||
writel(0x0, priv->dramc_ao + DRAMC_SHURK1_SELPH_ODTEN0);
|
||||
writel(0x0, priv->dramc_ao + DRAMC_SHURK1_SELPH_ODTEN1);
|
||||
writel(0x0, priv->dramc_ao + DRAMC_SHURK2_SELPH_ODTEN0);
|
||||
writel(0x66666666, priv->dramc_ao + DRAMC_SHURK2_SELPH_ODTEN1);
|
||||
writel(0x2c000b0f, priv->dramc_ao + DRAMC_SHU_CONF1);
|
||||
writel(0x11111111, priv->dramc_ao + DRAMC_SHURK0_SELPH_DQSG0);
|
||||
writel(0x64646464, priv->dramc_ao + DRAMC_SHURK0_SELPH_DQSG1);
|
||||
writel(0x11111111, priv->dramc_ao + DRAMC_SHURK1_SELPH_DQSG0);
|
||||
writel(0x64646464, priv->dramc_ao + DRAMC_SHURK1_SELPH_DQSG1);
|
||||
writel(0xc0c0c0c, priv->ddrphy + DDRPHY_SHU1_R0_B0_DQ2);
|
||||
writel(0xc0c0c0c, priv->ddrphy + DDRPHY_SHU1_R0_B0_DQ3);
|
||||
writel(0xc0c0c0c, priv->ddrphy + DDRPHY_SHU1_R0_B0_DQ4);
|
||||
writel(0xc0c0c0c, priv->ddrphy + DDRPHY_SHU1_R0_B0_DQ5);
|
||||
writel(0x0, priv->ddrphy + DDRPHY_SHU1_R0_B0_DQ6);
|
||||
writel(0xc0c0c0c, priv->ddrphy + DDRPHY_SHU1_R1_B0_DQ2);
|
||||
writel(0xc0c0c0c, priv->ddrphy + DDRPHY_SHU1_R1_B0_DQ3);
|
||||
writel(0xc0c0c0c, priv->ddrphy + DDRPHY_SHU1_R1_B0_DQ4);
|
||||
writel(0xc0c0c0c, priv->ddrphy + DDRPHY_SHU1_R1_B0_DQ5);
|
||||
writel(0x0, priv->ddrphy + DDRPHY_SHU1_R1_B0_DQ6);
|
||||
writel(0xc0c0c0c, priv->ddrphy + DDRPHY_SHU1_R0_B1_DQ2);
|
||||
writel(0xc0c0c0c, priv->ddrphy + DDRPHY_SHU1_R0_B1_DQ3);
|
||||
writel(0xc0c0c0c, priv->ddrphy + DDRPHY_SHU1_R0_B1_DQ4);
|
||||
writel(0xc0c0c0c, priv->ddrphy + DDRPHY_SHU1_R0_B1_DQ5);
|
||||
writel(0x0, priv->ddrphy + DDRPHY_SHU1_R0_B1_DQ6);
|
||||
writel(0xc0c0c0c, priv->ddrphy + DDRPHY_SHU1_R1_B1_DQ2);
|
||||
writel(0xc0c0c0c, priv->ddrphy + DDRPHY_SHU1_R1_B1_DQ3);
|
||||
writel(0xc0c0c0c, priv->ddrphy + DDRPHY_SHU1_R1_B1_DQ4);
|
||||
writel(0xc0c0c0c, priv->ddrphy + DDRPHY_SHU1_R1_B1_DQ5);
|
||||
writel(0x0, priv->ddrphy + DDRPHY_SHU1_R1_B1_DQ6);
|
||||
writel(0x20000001, priv->dramc_ao + DRAMC_SHU_RANKCTL);
|
||||
writel(0x2, priv->dramc_ao + DRAMC_SHURK0_DQSCTL);
|
||||
writel(0x2, priv->dramc_ao + DRAMC_SHURK1_DQSCTL);
|
||||
writel(0x4020b07, priv->dramc_ao + DRAMC_SHU_ACTIM0);
|
||||
writel(0xb060400, priv->dramc_ao + DRAMC_SHU_ACTIM1);
|
||||
writel(0x8090200, priv->dramc_ao + DRAMC_SHU_ACTIM2);
|
||||
writel(0x810018, priv->dramc_ao + DRAMC_SHU_ACTIM3);
|
||||
writel(0x1e9700ff, priv->dramc_ao + DRAMC_SHU_ACTIM4);
|
||||
writel(0x1000908, priv->dramc_ao + DRAMC_SHU_ACTIM5);
|
||||
writel(0x801040b, priv->dramc_ao + DRAMC_SHU_ACTIM_XRT);
|
||||
writel(0x20000D1, priv->dramc_ao + DRAMC_SHU_AC_TIME_05T);
|
||||
writel(0x80010000, priv->ddrphy + DDRPHY_PLL2);
|
||||
udelay(500);
|
||||
|
||||
writel(0x81080000, priv->dramc_ao + DRAMC_MISCTL0);
|
||||
writel(0xacf13, priv->dramc_ao + DRAMC_PERFCTL0);
|
||||
writel(0xacf12, priv->dramc_ao + DRAMC_PERFCTL0);
|
||||
writel(0x80, priv->dramc_ao + DRAMC_ARBCTL);
|
||||
writel(0x9, priv->dramc_ao + DRAMC_PADCTRL);
|
||||
writel(0x80000107, priv->dramc_ao + DRAMC_DRAMC_PD_CTRL);
|
||||
writel(0x3000000c, priv->dramc_ao + DRAMC_CLKCTRL);
|
||||
writel(0x25714001, priv->dramc_ao + DRAMC_REFCTRL0);
|
||||
writel(0x35b1f1cf, priv->dramc_ao + DRAMC_SPCMDCTRL);
|
||||
writel(0x4300000, priv->dramc_ao + DRAMC_CATRAINING1);
|
||||
writel(0xb0300000, priv->dramc_ao + DRAMC_STBCAL);
|
||||
writel(0x731414, priv->dramc_ao + DRAMC_RKCFG);
|
||||
writel(0x733414, priv->dramc_ao + DRAMC_RKCFG);
|
||||
udelay(20);
|
||||
|
||||
writel(0x80002050, priv->dramc_ao + DRAMC_CKECTRL);
|
||||
udelay(100);
|
||||
|
||||
writel(0x400000, priv->dramc_ao + DRAMC_MRS);
|
||||
writel(0x401800, priv->dramc_ao + DRAMC_MRS);
|
||||
writel(0x1, priv->dramc_ao + DRAMC_SPCMD);
|
||||
writel(0x0, priv->dramc_ao + DRAMC_SPCMD);
|
||||
udelay(100);
|
||||
|
||||
writel(0x601800, priv->dramc_ao + DRAMC_MRS);
|
||||
writel(0x600000, priv->dramc_ao + DRAMC_MRS);
|
||||
writel(0x1, priv->dramc_ao + DRAMC_SPCMD);
|
||||
writel(0x0, priv->dramc_ao + DRAMC_SPCMD);
|
||||
udelay(100);
|
||||
|
||||
writel(0x200000, priv->dramc_ao + DRAMC_MRS);
|
||||
writel(0x200400, priv->dramc_ao + DRAMC_MRS);
|
||||
writel(0x1, priv->dramc_ao + DRAMC_SPCMD);
|
||||
writel(0x0, priv->dramc_ao + DRAMC_SPCMD);
|
||||
udelay(100);
|
||||
|
||||
writel(0x400, priv->dramc_ao + DRAMC_MRS);
|
||||
writel(0x1d7000, priv->dramc_ao + DRAMC_MRS);
|
||||
writel(0x1, priv->dramc_ao + DRAMC_SPCMD);
|
||||
writel(0x0, priv->dramc_ao + DRAMC_SPCMD);
|
||||
udelay(100);
|
||||
|
||||
writel(0x702201, priv->dramc_ao + DRAMC_DRAMCTRL);
|
||||
writel(0x10, priv->dramc_ao + DRAMC_SPCMD);
|
||||
writel(0x0, priv->dramc_ao + DRAMC_SPCMD);
|
||||
writel(0x20, priv->dramc_ao + DRAMC_SPCMD);
|
||||
writel(0x0, priv->dramc_ao + DRAMC_SPCMD);
|
||||
writel(0x1, priv->dramc_ao + DRAMC_HW_MRR_FUN);
|
||||
writel(0x702301, priv->dramc_ao + DRAMC_DRAMCTRL);
|
||||
writel(0x702301, priv->dramc_ao + DRAMC_DRAMCTRL);
|
||||
writel(0xa56, priv->dramc_ao + DRAMC_ZQCS);
|
||||
writel(0xff0000, priv->dramc_ao + DRAMC_SHU_CONF3);
|
||||
writel(0x15b1f1cf, priv->dramc_ao + DRAMC_SPCMDCTRL);
|
||||
writel(0x2cb00b0f, priv->dramc_ao + DRAMC_SHU_CONF1);
|
||||
writel(0x65714001, priv->dramc_ao + DRAMC_REFCTRL0);
|
||||
writel(0x48000000, priv->dramc_ao + DRAMC_SREFCTRL);
|
||||
writel(0xc0000107, priv->dramc_ao + DRAMC_DRAMC_PD_CTRL);
|
||||
writel(0x10002, priv->dramc_ao + DRAMC_EYESCAN);
|
||||
writel(0x15e00, priv->dramc_ao + DRAMC_STBCAL1);
|
||||
writel(0x100000, priv->dramc_ao + DRAMC_TEST2_1);
|
||||
writel(0x4000, priv->dramc_ao + DRAMC_TEST2_2);
|
||||
writel(0x12000480, priv->dramc_ao + DRAMC_TEST2_3);
|
||||
writel(0x301d007, priv->dramc_ao + DRAMC_SHUCTRL2);
|
||||
writel(0x4782321, priv->dramc_ao + DRAMC_DRAMCTRL);
|
||||
writel(0x30210000, priv->dramc_ao + DRAMC_SHU_CKECTRL);
|
||||
writel(0x20000, priv->dramc_ao + DRAMC_DUMMY_RD);
|
||||
writel(0x4080110d, priv->dramc_ao + DRAMC_TEST2_4);
|
||||
writel(0x30000721, priv->dramc_ao + DRAMC_REFCTRL1);
|
||||
writel(0x0, priv->dramc_ao + DRAMC_RSTMASK);
|
||||
writel(0x4782320, priv->dramc_ao + DRAMC_DRAMCTRL);
|
||||
writel(0x80002000, priv->dramc_ao + DRAMC_CKECTRL);
|
||||
writel(0x45714001, priv->dramc_ao + DRAMC_REFCTRL0);
|
||||
|
||||
/* Apply config before calibration */
|
||||
writel(0x120, priv->dramc_ao + DRAMC_DRAMC_PD_CTRL);
|
||||
writel(0x11351131, priv->ddrphy + DDRPHY_MISC_CTRL3);
|
||||
writel(0xffffffff, priv->ddrphy + DDRPHY_MISC_CG_CTRL0);
|
||||
writel(0x2a7fe, priv->dramc_ao + DRAMC_SHU_SCINTV);
|
||||
writel(0xff01ff, priv->dramc_ao + DRAMC_SHU_CONF3);
|
||||
writel(0x4782320, priv->dramc_ao + DRAMC_DRAMCTRL);
|
||||
writel(0xa56, priv->dramc_ao + DRAMC_ZQCS);
|
||||
writel(0x80000000, priv->dramc_ao + DRAMC_SHU1_WODT);
|
||||
writel(0x21, priv->ddrphy + DDRPHY_SHU1_B0_DQ7);
|
||||
writel(0x1, priv->ddrphy + DDRPHY_SHU1_B1_DQ7);
|
||||
writel(0x35b1f1cf, priv->dramc_ao + DRAMC_SPCMDCTRL);
|
||||
writel(0x35b1f1cf, priv->dramc_ao + DRAMC_SPCMDCTRL);
|
||||
writel(0x35b1f1cf, priv->dramc_ao + DRAMC_SPCMDCTRL);
|
||||
writel(0xb0300000, priv->dramc_ao + DRAMC_STBCAL);
|
||||
writel(0xb0300000, priv->dramc_ao + DRAMC_STBCAL);
|
||||
writel(0x10002, priv->dramc_ao + DRAMC_EYESCAN);
|
||||
writel(0x8100008c, priv->ddrphy + DDRPHY_MISC_CTRL1);
|
||||
writel(0x45714001, priv->dramc_ao + DRAMC_REFCTRL0);
|
||||
writel(0xb0300000, priv->dramc_ao + DRAMC_STBCAL);
|
||||
writel(0xb0300000, priv->dramc_ao + DRAMC_STBCAL);
|
||||
|
||||
/* Write leveling */
|
||||
writel(0x1f2e2e00, priv->ddrphy + DDRPHY_SHU1_R0_B0_DQ7);
|
||||
writel(0x202f2f00, priv->ddrphy + DDRPHY_SHU1_R0_B1_DQ7);
|
||||
writel(0x33221100, priv->dramc_ao + DRAMC_SHU_SELPH_DQS1);
|
||||
writel(0x11112222, priv->dramc_ao + DRAMC_SHU_SELPH_DQS0);
|
||||
|
||||
/* RX dqs gating cal */
|
||||
writel(0x11111010, priv->dramc_ao + DRAMC_SHURK0_SELPH_DQSG0);
|
||||
writel(0x20201717, priv->dramc_ao + DRAMC_SHURK0_SELPH_DQSG1);
|
||||
writel(0x1d1f, priv->dramc_ao + DRAMC_SHURK0_DQSIEN);
|
||||
|
||||
/* RX window per-bit cal */
|
||||
writel(0x03030404, priv->ddrphy + DDRPHY_SHU1_R0_B0_DQ2);
|
||||
writel(0x01010303, priv->ddrphy + DDRPHY_SHU1_R0_B0_DQ3);
|
||||
writel(0x01010303, priv->ddrphy + DDRPHY_SHU1_R0_B0_DQ4);
|
||||
writel(0x01010000, priv->ddrphy + DDRPHY_SHU1_R0_B0_DQ5);
|
||||
writel(0x03030606, priv->ddrphy + DDRPHY_SHU1_R0_B1_DQ2);
|
||||
writel(0x02020202, priv->ddrphy + DDRPHY_SHU1_R0_B1_DQ3);
|
||||
writel(0x04040303, priv->ddrphy + DDRPHY_SHU1_R0_B1_DQ4);
|
||||
writel(0x06060101, priv->ddrphy + DDRPHY_SHU1_R0_B1_DQ5);
|
||||
|
||||
/* RX datlat cal */
|
||||
writel(0x28b00a0e, priv->dramc_ao + DRAMC_SHU_CONF1);
|
||||
|
||||
/* TX window per-byte with 2UI cal */
|
||||
writel(0x11112222, priv->dramc_ao + DRAMC_SHURK0_SELPH_DQ0);
|
||||
writel(0x22220000, priv->dramc_ao + DRAMC_SHURK0_SELPH_DQ2);
|
||||
writel(0x11112222, priv->dramc_ao + DRAMC_SHURK0_SELPH_DQ1);
|
||||
writel(0x22220000, priv->dramc_ao + DRAMC_SHURK0_SELPH_DQ3);
|
||||
writel(0x1f2e2e00, priv->ddrphy + DDRPHY_SHU1_R0_B0_DQ7);
|
||||
writel(0x202f2f00, priv->ddrphy + DDRPHY_SHU1_R0_B1_DQ7);
|
||||
|
||||
return mtk_ddr3_rank_size_detect(dev);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int mtk_ddr3_probe(struct udevice *dev)
|
||||
{
|
||||
struct mtk_ddr3_priv *priv = dev_get_priv(dev);
|
||||
|
||||
priv->emi = dev_read_addr_index(dev, 0);
|
||||
if (priv->emi == FDT_ADDR_T_NONE)
|
||||
return -EINVAL;
|
||||
|
||||
priv->ddrphy = dev_read_addr_index(dev, 1);
|
||||
if (priv->ddrphy == FDT_ADDR_T_NONE)
|
||||
return -EINVAL;
|
||||
|
||||
priv->dramc_ao = dev_read_addr_index(dev, 2);
|
||||
if (priv->dramc_ao == FDT_ADDR_T_NONE)
|
||||
return -EINVAL;
|
||||
|
||||
#ifdef CONFIG_SPL_BUILD
|
||||
int ret;
|
||||
|
||||
ret = clk_get_by_index(dev, 0, &priv->phy);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = clk_get_by_index(dev, 1, &priv->phy_mux);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = clk_get_by_index(dev, 2, &priv->mem);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = clk_get_by_index(dev, 3, &priv->mem_mux);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = mtk_ddr3_init(dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mtk_ddr3_get_info(struct udevice *dev, struct ram_info *info)
|
||||
{
|
||||
struct mtk_ddr3_priv *priv = dev_get_priv(dev);
|
||||
u32 val = readl(priv->emi + EMI_CONA);
|
||||
|
||||
info->base = CONFIG_SYS_SDRAM_BASE;
|
||||
|
||||
switch ((val & EMI_COL_ADDR_MASK) >> EMI_COL_ADDR_SHIFT) {
|
||||
case 0:
|
||||
info->size = SZ_128M;
|
||||
break;
|
||||
case 1:
|
||||
info->size = SZ_256M;
|
||||
break;
|
||||
case 2:
|
||||
info->size = SZ_512M;
|
||||
break;
|
||||
case 3:
|
||||
info->size = SZ_1G;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct ram_ops mtk_ddr3_ops = {
|
||||
.get_info = mtk_ddr3_get_info,
|
||||
};
|
||||
|
||||
static const struct udevice_id mtk_ddr3_ids[] = {
|
||||
{ .compatible = "mediatek,mt7629-dramc" },
|
||||
{ }
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(mediatek_ddr3) = {
|
||||
.name = "mediatek_ddr3",
|
||||
.id = UCLASS_RAM,
|
||||
.of_match = mtk_ddr3_ids,
|
||||
.ops = &mtk_ddr3_ops,
|
||||
.probe = mtk_ddr3_probe,
|
||||
.priv_auto_alloc_size = sizeof(struct mtk_ddr3_priv),
|
||||
};
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,27 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright (C) 2015 Google, Inc
|
||||
* Written by Simon Glass <sjg@chromium.org>
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <ram.h>
|
||||
#include <dm.h>
|
||||
#include <errno.h>
|
||||
#include <dm/lists.h>
|
||||
#include <dm/root.h>
|
||||
|
||||
int ram_get_info(struct udevice *dev, struct ram_info *info)
|
||||
{
|
||||
struct ram_ops *ops = ram_get_ops(dev);
|
||||
|
||||
if (!ops->get_info)
|
||||
return -ENOSYS;
|
||||
|
||||
return ops->get_info(dev, info);
|
||||
}
|
||||
|
||||
UCLASS_DRIVER(ram) = {
|
||||
.id = UCLASS_RAM,
|
||||
.name = "ram",
|
||||
};
|
||||
@@ -0,0 +1,30 @@
|
||||
config RAM_ROCKCHIP
|
||||
bool "Ram drivers support for Rockchip SoCs"
|
||||
depends on RAM && ARCH_ROCKCHIP
|
||||
default y
|
||||
help
|
||||
This enables support for ram drivers Rockchip SoCs.
|
||||
|
||||
config ROCKCHIP_SDRAM_COMMON
|
||||
bool "Enable rockchip sdram common driver"
|
||||
depends on TPL_RAM || SPL_RAM
|
||||
help
|
||||
This enable sdram common driver
|
||||
|
||||
config RAM_ROCKCHIP_DEBUG
|
||||
bool "Rockchip ram drivers debugging"
|
||||
default y
|
||||
help
|
||||
This enables debugging ram driver API's for the platforms
|
||||
based on Rockchip SoCs.
|
||||
|
||||
This is an option for developers to understand the ram drivers
|
||||
initialization, configurations and etc.
|
||||
|
||||
config RAM_RK3399_LPDDR4
|
||||
bool "LPDDR4 support for Rockchip RK3399"
|
||||
depends on RAM_ROCKCHIP && ROCKCHIP_RK3399
|
||||
help
|
||||
This enables LPDDR4 sdram code support for the platforms based
|
||||
on Rockchip RK3399 SoC.
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
# SPDX-License-Identifier: GPL-2.0+
|
||||
#
|
||||
# Copyright (c) 2017 Theobroma Systems Design und Consulting GmbH
|
||||
#
|
||||
|
||||
obj-$(CONFIG_ROCKCHIP_PX30) += sdram_px30.o sdram_pctl_px30.o sdram_phy_px30.o
|
||||
obj-$(CONFIG_ROCKCHIP_RK3368) = dmc-rk3368.o
|
||||
obj-$(CONFIG_ROCKCHIP_RK3128) = sdram_rk3128.o
|
||||
obj-$(CONFIG_ROCKCHIP_RK3188) = sdram_rk3188.o
|
||||
obj-$(CONFIG_ROCKCHIP_RK322X) = sdram_rk322x.o
|
||||
obj-$(CONFIG_ROCKCHIP_RK3288) = sdram_rk3288.o
|
||||
obj-$(CONFIG_ROCKCHIP_RK3308) = sdram_rk3308.o
|
||||
obj-$(CONFIG_ROCKCHIP_RK3328) = sdram_rk3328.o sdram_pctl_px30.o sdram_phy_px30.o
|
||||
obj-$(CONFIG_ROCKCHIP_RK3399) += sdram_rk3399.o
|
||||
obj-$(CONFIG_ROCKCHIP_SDRAM_COMMON) += sdram_common.o
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,72 @@
|
||||
{
|
||||
{
|
||||
{
|
||||
.rank = 0x1,
|
||||
.col = 0xC,
|
||||
.bk = 0x3,
|
||||
.bw = 0x1,
|
||||
.dbw = 0x0,
|
||||
.row_3_4 = 0x0,
|
||||
.cs0_row = 0x10,
|
||||
.cs1_row = 0x10,
|
||||
.cs0_high16bit_row = 0x10,
|
||||
.cs1_high16bit_row = 0x10,
|
||||
.ddrconfig = 0,
|
||||
},
|
||||
{
|
||||
{0x290b0609},
|
||||
{0x08020401},
|
||||
{0x00000002},
|
||||
{0x00001111},
|
||||
{0x0000000c},
|
||||
{0x00000222},
|
||||
0x000000ff
|
||||
}
|
||||
},
|
||||
{
|
||||
.ddr_freq = 333,
|
||||
.dramtype = DDR3,
|
||||
.num_channels = 1,
|
||||
.stride = 0,
|
||||
.odt = 0,
|
||||
},
|
||||
{
|
||||
{
|
||||
{0x00000000, 0x43041001}, /* MSTR */
|
||||
{0x00000064, 0x0028003b}, /* RFSHTMG */
|
||||
{0x000000d0, 0x00020053}, /* INIT0 */
|
||||
{0x000000d4, 0x00020000}, /* INIT1 */
|
||||
{0x000000d8, 0x00000100}, /* INIT2 */
|
||||
{0x000000dc, 0x03200000}, /* INIT3 */
|
||||
{0x000000e0, 0x00000000}, /* INIT4 */
|
||||
{0x000000e4, 0x00090000}, /* INIT5 */
|
||||
{0x000000f4, 0x000f012f}, /* RANKCTL */
|
||||
{0x00000100, 0x07090b06}, /* DRAMTMG0 */
|
||||
{0x00000104, 0x00050209}, /* DRAMTMG1 */
|
||||
{0x00000108, 0x03030407}, /* DRAMTMG2 */
|
||||
{0x0000010c, 0x00202006}, /* DRAMTMG3 */
|
||||
{0x00000110, 0x03020204}, /* DRAMTMG4 */
|
||||
{0x00000114, 0x03030202}, /* DRAMTMG5 */
|
||||
{0x00000120, 0x00000903}, /* DRAMTMG8 */
|
||||
{0x00000180, 0x00800020}, /* ZQCTL0 */
|
||||
{0x00000184, 0x00000000}, /* ZQCTL1 */
|
||||
{0x00000190, 0x07010001}, /* DFITMG0 */
|
||||
{0x00000198, 0x07000101}, /* DFILPCFG0 */
|
||||
{0x000001a0, 0xc0400003}, /* DFIUPD0 */
|
||||
{0x00000240, 0x06000604}, /* ODTCFG */
|
||||
{0x00000244, 0x00000201}, /* ODTMAP */
|
||||
{0x00000250, 0x00001f00}, /* SCHED */
|
||||
{0x00000490, 0x00000001}, /* PCTRL_0 */
|
||||
{0xffffffff, 0xffffffff}
|
||||
}
|
||||
},
|
||||
{
|
||||
{
|
||||
{0x00000004, 0x0000000a}, /* PHYREG01 */
|
||||
{0x00000028, 0x00000006}, /* PHYREG0A */
|
||||
{0x0000002c, 0x00000000}, /* PHYREG0B */
|
||||
{0x00000030, 0x00000005}, /* PHYREG0C */
|
||||
{0xffffffff, 0xffffffff}
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -0,0 +1,75 @@
|
||||
{
|
||||
{
|
||||
{
|
||||
.rank = 0x1,
|
||||
.col = 0xA,
|
||||
.bk = 0x2,
|
||||
.bw = 0x1,
|
||||
.dbw = 0x0,
|
||||
.row_3_4 = 0x0,
|
||||
.cs0_row = 0x11,
|
||||
.cs1_row = 0x0,
|
||||
.cs0_high16bit_row = 0x11,
|
||||
.cs1_high16bit_row = 0x0,
|
||||
.ddrconfig = 0,
|
||||
},
|
||||
{
|
||||
{0x4d110a08},
|
||||
{0x06020501},
|
||||
{0x00000002},
|
||||
{0x00001111},
|
||||
{0x0000000c},
|
||||
{0x0000022a},
|
||||
0x000000ff
|
||||
}
|
||||
},
|
||||
{
|
||||
.ddr_freq = 333,
|
||||
.dramtype = DDR4,
|
||||
.num_channels = 1,
|
||||
.stride = 0,
|
||||
.odt = 0,
|
||||
},
|
||||
{
|
||||
{
|
||||
{0x00000000, 0x43049010}, /* MSTR */
|
||||
{0x00000064, 0x0028003b}, /* RFSHTMG */
|
||||
{0x000000d0, 0x00020053}, /* INIT0 */
|
||||
{0x000000d4, 0x00220000}, /* INIT1 */
|
||||
{0x000000d8, 0x00000100}, /* INIT2 */
|
||||
{0x000000dc, 0x00040000}, /* INIT3 */
|
||||
{0x000000e0, 0x00000000}, /* INIT4 */
|
||||
{0x000000e4, 0x00110000}, /* INIT5 */
|
||||
{0x000000e8, 0x00000420}, /* INIT6 */
|
||||
{0x000000ec, 0x00000400}, /* INIT7 */
|
||||
{0x000000f4, 0x000f012f}, /* RANKCTL */
|
||||
{0x00000100, 0x09060b06}, /* DRAMTMG0 */
|
||||
{0x00000104, 0x00020209}, /* DRAMTMG1 */
|
||||
{0x00000108, 0x0505040a}, /* DRAMTMG2 */
|
||||
{0x0000010c, 0x0040400c}, /* DRAMTMG3 */
|
||||
{0x00000110, 0x05030206}, /* DRAMTMG4 */
|
||||
{0x00000114, 0x03030202}, /* DRAMTMG5 */
|
||||
{0x00000120, 0x03030b03}, /* DRAMTMG8 */
|
||||
{0x00000124, 0x00020208}, /* DRAMTMG9 */
|
||||
{0x00000180, 0x01000040}, /* ZQCTL0 */
|
||||
{0x00000184, 0x00000000}, /* ZQCTL1 */
|
||||
{0x00000190, 0x07030003}, /* DFITMG0 */
|
||||
{0x00000198, 0x07000101}, /* DFILPCFG0 */
|
||||
{0x000001a0, 0xc0400003}, /* DFIUPD0 */
|
||||
{0x00000240, 0x06000604}, /* ODTCFG */
|
||||
{0x00000244, 0x00000201}, /* ODTMAP */
|
||||
{0x00000250, 0x00001f00}, /* SCHED */
|
||||
{0x00000490, 0x00000001}, /* PCTRL_0 */
|
||||
{0xffffffff, 0xffffffff}
|
||||
}
|
||||
},
|
||||
{
|
||||
{
|
||||
{0x00000004, 0x0000000c}, /* PHYREG01 */
|
||||
{0x00000028, 0x0000000a}, /* PHYREG0A */
|
||||
{0x0000002c, 0x00000000}, /* PHYREG0B */
|
||||
{0x00000030, 0x00000009}, /* PHYREG0C */
|
||||
{0xffffffff, 0xffffffff}
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -0,0 +1,121 @@
|
||||
{
|
||||
0x77,
|
||||
0x88,
|
||||
0x79,
|
||||
0x79,
|
||||
0x87,
|
||||
0x97,
|
||||
0x87,
|
||||
0x78,
|
||||
0x77,
|
||||
0x78,
|
||||
0x87,
|
||||
0x88,
|
||||
0x87,
|
||||
0x87,
|
||||
0x77
|
||||
},
|
||||
{
|
||||
0x78,
|
||||
0x78,
|
||||
0x78,
|
||||
0x78,
|
||||
0x78,
|
||||
0x78,
|
||||
0x78,
|
||||
0x78,
|
||||
0x78,
|
||||
0x69,
|
||||
0x9,
|
||||
},
|
||||
{
|
||||
0x77,
|
||||
0x78,
|
||||
0x77,
|
||||
0x78,
|
||||
0x77,
|
||||
0x78,
|
||||
0x77,
|
||||
0x78,
|
||||
0x77,
|
||||
0x79,
|
||||
0x9,
|
||||
},
|
||||
{
|
||||
0x78,
|
||||
0x78,
|
||||
0x78,
|
||||
0x78,
|
||||
0x78,
|
||||
0x78,
|
||||
0x78,
|
||||
0x78,
|
||||
0x78,
|
||||
0x69,
|
||||
0x9,
|
||||
},
|
||||
{
|
||||
0x77,
|
||||
0x78,
|
||||
0x77,
|
||||
0x77,
|
||||
0x77,
|
||||
0x77,
|
||||
0x77,
|
||||
0x77,
|
||||
0x77,
|
||||
0x79,
|
||||
0x9,
|
||||
},
|
||||
{
|
||||
0x78,
|
||||
0x78,
|
||||
0x78,
|
||||
0x78,
|
||||
0x78,
|
||||
0x78,
|
||||
0x78,
|
||||
0x78,
|
||||
0x78,
|
||||
0x69,
|
||||
0x9,
|
||||
},
|
||||
{
|
||||
0x77,
|
||||
0x78,
|
||||
0x77,
|
||||
0x78,
|
||||
0x77,
|
||||
0x78,
|
||||
0x77,
|
||||
0x78,
|
||||
0x77,
|
||||
0x79,
|
||||
0x9,
|
||||
},
|
||||
{
|
||||
0x78,
|
||||
0x78,
|
||||
0x78,
|
||||
0x78,
|
||||
0x78,
|
||||
0x78,
|
||||
0x78,
|
||||
0x78,
|
||||
0x78,
|
||||
0x69,
|
||||
0x9,
|
||||
},
|
||||
{
|
||||
0x77,
|
||||
0x78,
|
||||
0x77,
|
||||
0x77,
|
||||
0x77,
|
||||
0x77,
|
||||
0x77,
|
||||
0x77,
|
||||
0x77,
|
||||
0x79,
|
||||
0x9,
|
||||
}
|
||||
+73
@@ -0,0 +1,73 @@
|
||||
{
|
||||
{
|
||||
{
|
||||
.rank = 0x1,
|
||||
.col = 0xC,
|
||||
.bk = 0x3,
|
||||
.bw = 0x1,
|
||||
.dbw = 0x0,
|
||||
.row_3_4 = 0x0,
|
||||
.cs0_row = 0xF,
|
||||
.cs1_row = 0xF,
|
||||
.cs0_high16bit_row = 0xF,
|
||||
.cs1_high16bit_row = 0xF,
|
||||
.ddrconfig = 0,
|
||||
},
|
||||
{
|
||||
{0x2b0c070a},
|
||||
{0x08020303},
|
||||
{0x00000002},
|
||||
{0x00001111},
|
||||
{0x0000000c},
|
||||
{0x00000219},
|
||||
0x000000ff
|
||||
}
|
||||
},
|
||||
{
|
||||
.ddr_freq = 333,
|
||||
.dramtype = LPDDR2,
|
||||
.num_channels = 1,
|
||||
.stride = 0,
|
||||
.odt = 0,
|
||||
},
|
||||
{
|
||||
{
|
||||
{0x00000000, 0x41041004}, /* MSTR */
|
||||
{0x00000064, 0x00140023}, /* RFSHTMG */
|
||||
{0x000000d0, 0x00220002}, /* INIT0 */
|
||||
{0x000000d4, 0x00010000}, /* INIT1 */
|
||||
{0x000000d8, 0x00000703}, /* INIT2 */
|
||||
{0x000000dc, 0x00630005}, /* INIT3 */
|
||||
{0x000000e0, 0x00010000}, /* INIT4 */
|
||||
{0x000000e4, 0x00070003}, /* INIT5 */
|
||||
{0x000000f4, 0x000f012f}, /* RANKCTL */
|
||||
{0x00000100, 0x07090b07}, /* DRAMTMG0 */
|
||||
{0x00000104, 0x0002010b}, /* DRAMTMG1 */
|
||||
{0x00000108, 0x02040506}, /* DRAMTMG2 */
|
||||
{0x0000010c, 0x00303000}, /* DRAMTMG3 */
|
||||
{0x00000110, 0x04010204}, /* DRAMTMG4 */
|
||||
{0x00000114, 0x01010303}, /* DRAMTMG5 */
|
||||
{0x00000118, 0x02020003}, /* DRAMTMG6 */
|
||||
{0x00000120, 0x00000303}, /* DRAMTMG8 */
|
||||
{0x00000138, 0x00000025}, /* DRAMTMG14 */
|
||||
{0x00000180, 0x003c000f}, /* ZQCTL0 */
|
||||
{0x00000184, 0x00900000}, /* ZQCTL1 */
|
||||
{0x00000190, 0x07020001}, /* DFITMG0 */
|
||||
{0x00000198, 0x07000101}, /* DFILPCFG0 */
|
||||
{0x000001a0, 0xc0400003}, /* DFIUPD0 */
|
||||
{0x00000240, 0x07030718}, /* ODTCFG */
|
||||
{0x00000250, 0x00001f00}, /* SCHED */
|
||||
{0x00000490, 0x00000001}, /* PCTRL_0 */
|
||||
{0xffffffff, 0xffffffff}
|
||||
}
|
||||
},
|
||||
{
|
||||
{
|
||||
{0x00000004, 0x00000009}, /* PHYREG01 */
|
||||
{0x00000028, 0x00000007}, /* PHYREG0A */
|
||||
{0x0000002c, 0x00000000}, /* PHYREG0B */
|
||||
{0x00000030, 0x00000004}, /* PHYREG0C */
|
||||
{0xffffffff, 0xffffffff}
|
||||
}
|
||||
}
|
||||
},
|
||||
+74
@@ -0,0 +1,74 @@
|
||||
{
|
||||
{
|
||||
{
|
||||
.rank = 0x1,
|
||||
.col = 0xC,
|
||||
.bk = 0x3,
|
||||
.bw = 0x1,
|
||||
.dbw = 0x0,
|
||||
.row_3_4 = 0x0,
|
||||
.cs0_row = 0x10,
|
||||
.cs1_row = 0x10,
|
||||
.cs0_high16bit_row = 0x10,
|
||||
.cs1_high16bit_row = 0x10,
|
||||
.ddrconfig = 0,
|
||||
},
|
||||
{
|
||||
{0x290a060a},
|
||||
{0x08020303},
|
||||
{0x00000002},
|
||||
{0x00001111},
|
||||
{0x0000000c},
|
||||
{0x0000021a},
|
||||
0x000000ff
|
||||
}
|
||||
},
|
||||
{
|
||||
.ddr_freq = 333,
|
||||
.dramtype = LPDDR3,
|
||||
.num_channels = 1,
|
||||
.stride = 0,
|
||||
.odt = 0,
|
||||
},
|
||||
{
|
||||
{
|
||||
{0x00000000, 0x43041008}, /* MSTR */
|
||||
{0x00000064, 0x00140023}, /* RFSHTMG */
|
||||
{0x000000d0, 0x00220002}, /* INIT0 */
|
||||
{0x000000d4, 0x00010000}, /* INIT1 */
|
||||
{0x000000d8, 0x00000703}, /* INIT2 */
|
||||
{0x000000dc, 0x00830004}, /* INIT3 */
|
||||
{0x000000e0, 0x00010000}, /* INIT4 */
|
||||
{0x000000e4, 0x00070003}, /* INIT5 */
|
||||
{0x000000f4, 0x000f012f}, /* RANKCTL */
|
||||
{0x00000100, 0x06090b07}, /* DRAMTMG0 */
|
||||
{0x00000104, 0x0002020b}, /* DRAMTMG1 */
|
||||
{0x00000108, 0x02030506}, /* DRAMTMG2 */
|
||||
{0x0000010c, 0x00505000}, /* DRAMTMG3 */
|
||||
{0x00000110, 0x03020204}, /* DRAMTMG4 */
|
||||
{0x00000114, 0x01010303}, /* DRAMTMG5 */
|
||||
{0x00000118, 0x02020003}, /* DRAMTMG6 */
|
||||
{0x00000120, 0x00000303}, /* DRAMTMG8 */
|
||||
{0x00000138, 0x00000025}, /* DRAMTMG14 */
|
||||
{0x00000180, 0x003c000f}, /* ZQCTL0 */
|
||||
{0x00000184, 0x00900000}, /* ZQCTL1 */
|
||||
{0x00000190, 0x07020000}, /* DFITMG0 */
|
||||
{0x00000198, 0x07000101}, /* DFILPCFG0 */
|
||||
{0x000001a0, 0xc0400003}, /* DFIUPD0 */
|
||||
{0x00000240, 0x0900090c}, /* ODTCFG */
|
||||
{0x00000244, 0x00000101}, /* ODTMAP */
|
||||
{0x00000250, 0x00001f00}, /* SCHED */
|
||||
{0x00000490, 0x00000001}, /* PCTRL_0 */
|
||||
{0xffffffff, 0xffffffff}
|
||||
}
|
||||
},
|
||||
{
|
||||
{
|
||||
{0x00000004, 0x0000000b}, /* PHYREG01 */
|
||||
{0x00000028, 0x00000006}, /* PHYREG0A */
|
||||
{0x0000002c, 0x00000000}, /* PHYREG0B */
|
||||
{0x00000030, 0x00000003}, /* PHYREG0C */
|
||||
{0xffffffff, 0xffffffff}
|
||||
}
|
||||
}
|
||||
},
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,429 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* (C) Copyright 2018 Rockchip Electronics Co., Ltd.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <debug_uart.h>
|
||||
#include <ram.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/arch-rockchip/sdram.h>
|
||||
#include <asm/arch-rockchip/sdram_common.h>
|
||||
|
||||
#ifdef CONFIG_RAM_ROCKCHIP_DEBUG
|
||||
void sdram_print_dram_type(unsigned char dramtype)
|
||||
{
|
||||
switch (dramtype) {
|
||||
case DDR3:
|
||||
printascii("DDR3");
|
||||
break;
|
||||
case DDR4:
|
||||
printascii("DDR4");
|
||||
break;
|
||||
case LPDDR2:
|
||||
printascii("LPDDR2");
|
||||
break;
|
||||
case LPDDR3:
|
||||
printascii("LPDDR3");
|
||||
break;
|
||||
case LPDDR4:
|
||||
printascii("LPDDR4");
|
||||
break;
|
||||
default:
|
||||
printascii("Unknown Device");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void sdram_print_ddr_info(struct sdram_cap_info *cap_info,
|
||||
struct sdram_base_params *base)
|
||||
{
|
||||
u64 cap;
|
||||
u32 bg;
|
||||
|
||||
bg = (cap_info->dbw == 0) ? 2 : 1;
|
||||
|
||||
sdram_print_dram_type(base->dramtype);
|
||||
|
||||
printascii(", ");
|
||||
printdec(base->ddr_freq);
|
||||
printascii("MHz\n");
|
||||
|
||||
printascii("BW=");
|
||||
printdec(8 << cap_info->bw);
|
||||
printascii(" Col=");
|
||||
printdec(cap_info->col);
|
||||
printascii(" Bk=");
|
||||
printdec(0x1 << cap_info->bk);
|
||||
if (base->dramtype == DDR4) {
|
||||
printascii(" BG=");
|
||||
printdec(1 << bg);
|
||||
}
|
||||
printascii(" CS0 Row=");
|
||||
printdec(cap_info->cs0_row);
|
||||
if (cap_info->cs0_high16bit_row !=
|
||||
cap_info->cs0_row) {
|
||||
printascii("/");
|
||||
printdec(cap_info->cs0_high16bit_row);
|
||||
}
|
||||
if (cap_info->rank > 1) {
|
||||
printascii(" CS1 Row=");
|
||||
printdec(cap_info->cs1_row);
|
||||
if (cap_info->cs1_high16bit_row !=
|
||||
cap_info->cs1_row) {
|
||||
printascii("/");
|
||||
printdec(cap_info->cs1_high16bit_row);
|
||||
}
|
||||
}
|
||||
printascii(" CS=");
|
||||
printdec(cap_info->rank);
|
||||
printascii(" Die BW=");
|
||||
printdec(8 << cap_info->dbw);
|
||||
|
||||
cap = sdram_get_cs_cap(cap_info, 3, base->dramtype);
|
||||
if (cap_info->row_3_4)
|
||||
cap = cap * 3 / 4;
|
||||
|
||||
printascii(" Size=");
|
||||
printdec(cap >> 20);
|
||||
printascii("MB\n");
|
||||
}
|
||||
|
||||
void sdram_print_stride(unsigned int stride)
|
||||
{
|
||||
switch (stride) {
|
||||
case 0xc:
|
||||
printf("128B stride\n");
|
||||
break;
|
||||
case 5:
|
||||
case 9:
|
||||
case 0xd:
|
||||
case 0x11:
|
||||
case 0x19:
|
||||
printf("256B stride\n");
|
||||
break;
|
||||
case 0xa:
|
||||
case 0xe:
|
||||
case 0x12:
|
||||
printf("512B stride\n");
|
||||
break;
|
||||
case 0xf:
|
||||
printf("4K stride\n");
|
||||
break;
|
||||
case 0x1f:
|
||||
printf("32MB + 256B stride\n");
|
||||
break;
|
||||
default:
|
||||
printf("no stride\n");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* cs: 0:cs0
|
||||
* 1:cs1
|
||||
* else cs0+cs1
|
||||
* note: it didn't consider about row_3_4
|
||||
*/
|
||||
u64 sdram_get_cs_cap(struct sdram_cap_info *cap_info, u32 cs, u32 dram_type)
|
||||
{
|
||||
u32 bg;
|
||||
u64 cap[2];
|
||||
|
||||
if (dram_type == DDR4)
|
||||
/* DDR4 8bit dram BG = 2(4bank groups),
|
||||
* 16bit dram BG = 1 (2 bank groups)
|
||||
*/
|
||||
bg = (cap_info->dbw == 0) ? 2 : 1;
|
||||
else
|
||||
bg = 0;
|
||||
cap[0] = 1llu << (cap_info->bw + cap_info->col +
|
||||
bg + cap_info->bk + cap_info->cs0_row);
|
||||
|
||||
if (cap_info->rank == 2)
|
||||
cap[1] = 1llu << (cap_info->bw + cap_info->col +
|
||||
bg + cap_info->bk + cap_info->cs1_row);
|
||||
else
|
||||
cap[1] = 0;
|
||||
|
||||
if (cs == 0)
|
||||
return cap[0];
|
||||
else if (cs == 1)
|
||||
return cap[1];
|
||||
else
|
||||
return (cap[0] + cap[1]);
|
||||
}
|
||||
|
||||
/* n: Unit bytes */
|
||||
void sdram_copy_to_reg(u32 *dest, const u32 *src, u32 n)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < n / sizeof(u32); i++) {
|
||||
writel(*src, dest);
|
||||
src++;
|
||||
dest++;
|
||||
}
|
||||
}
|
||||
|
||||
void sdram_org_config(struct sdram_cap_info *cap_info,
|
||||
struct sdram_base_params *base,
|
||||
u32 *p_os_reg2, u32 *p_os_reg3, u32 channel)
|
||||
{
|
||||
*p_os_reg2 |= SYS_REG_ENC_DDRTYPE(base->dramtype);
|
||||
*p_os_reg2 |= SYS_REG_ENC_NUM_CH(base->num_channels);
|
||||
|
||||
*p_os_reg2 |= SYS_REG_ENC_ROW_3_4(cap_info->row_3_4, channel);
|
||||
*p_os_reg2 |= SYS_REG_ENC_CHINFO(channel);
|
||||
*p_os_reg2 |= SYS_REG_ENC_RANK(cap_info->rank, channel);
|
||||
*p_os_reg2 |= SYS_REG_ENC_COL(cap_info->col, channel);
|
||||
*p_os_reg2 |= SYS_REG_ENC_BK(cap_info->bk, channel);
|
||||
*p_os_reg2 |= SYS_REG_ENC_BW(cap_info->bw, channel);
|
||||
*p_os_reg2 |= SYS_REG_ENC_DBW(cap_info->dbw, channel);
|
||||
|
||||
SYS_REG_ENC_CS0_ROW(cap_info->cs0_row, *p_os_reg2, *p_os_reg3, channel);
|
||||
if (cap_info->cs1_row)
|
||||
SYS_REG_ENC_CS1_ROW(cap_info->cs1_row, *p_os_reg2,
|
||||
*p_os_reg3, channel);
|
||||
*p_os_reg3 |= SYS_REG_ENC_CS1_COL(cap_info->col, channel);
|
||||
*p_os_reg3 |= SYS_REG_ENC_VERSION(DDR_SYS_REG_VERSION);
|
||||
}
|
||||
|
||||
int sdram_detect_bw(struct sdram_cap_info *cap_info)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sdram_detect_cs(struct sdram_cap_info *cap_info)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sdram_detect_col(struct sdram_cap_info *cap_info,
|
||||
u32 coltmp)
|
||||
{
|
||||
void __iomem *test_addr;
|
||||
u32 col;
|
||||
u32 bw = cap_info->bw;
|
||||
|
||||
for (col = coltmp; col >= 9; col -= 1) {
|
||||
writel(0, CONFIG_SYS_SDRAM_BASE);
|
||||
test_addr = (void __iomem *)(CONFIG_SYS_SDRAM_BASE +
|
||||
(1ul << (col + bw - 1ul)));
|
||||
writel(PATTERN, test_addr);
|
||||
if ((readl(test_addr) == PATTERN) &&
|
||||
(readl(CONFIG_SYS_SDRAM_BASE) == 0))
|
||||
break;
|
||||
}
|
||||
if (col == 8) {
|
||||
printascii("col error\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
cap_info->col = col;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sdram_detect_bank(struct sdram_cap_info *cap_info,
|
||||
u32 coltmp, u32 bktmp)
|
||||
{
|
||||
void __iomem *test_addr;
|
||||
u32 bk;
|
||||
u32 bw = cap_info->bw;
|
||||
|
||||
test_addr = (void __iomem *)(CONFIG_SYS_SDRAM_BASE +
|
||||
(1ul << (coltmp + bktmp + bw - 1ul)));
|
||||
writel(0, CONFIG_SYS_SDRAM_BASE);
|
||||
writel(PATTERN, test_addr);
|
||||
if ((readl(test_addr) == PATTERN) &&
|
||||
(readl(CONFIG_SYS_SDRAM_BASE) == 0))
|
||||
bk = 3;
|
||||
else
|
||||
bk = 2;
|
||||
|
||||
cap_info->bk = bk;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* detect bg for ddr4 */
|
||||
int sdram_detect_bg(struct sdram_cap_info *cap_info,
|
||||
u32 coltmp)
|
||||
{
|
||||
void __iomem *test_addr;
|
||||
u32 dbw;
|
||||
u32 bw = cap_info->bw;
|
||||
|
||||
test_addr = (void __iomem *)(CONFIG_SYS_SDRAM_BASE +
|
||||
(1ul << (coltmp + bw + 1ul)));
|
||||
writel(0, CONFIG_SYS_SDRAM_BASE);
|
||||
writel(PATTERN, test_addr);
|
||||
if ((readl(test_addr) == PATTERN) &&
|
||||
(readl(CONFIG_SYS_SDRAM_BASE) == 0))
|
||||
dbw = 0;
|
||||
else
|
||||
dbw = 1;
|
||||
|
||||
cap_info->dbw = dbw;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* detect dbw for ddr3,lpddr2,lpddr3,lpddr4 */
|
||||
int sdram_detect_dbw(struct sdram_cap_info *cap_info, u32 dram_type)
|
||||
{
|
||||
u32 row, col, bk, bw, cs_cap, cs;
|
||||
u32 die_bw_0 = 0, die_bw_1 = 0;
|
||||
|
||||
if (dram_type == DDR3 || dram_type == LPDDR4) {
|
||||
cap_info->dbw = 1;
|
||||
} else if (dram_type == LPDDR3 || dram_type == LPDDR2) {
|
||||
row = cap_info->cs0_row;
|
||||
col = cap_info->col;
|
||||
bk = cap_info->bk;
|
||||
cs = cap_info->rank;
|
||||
bw = cap_info->bw;
|
||||
cs_cap = (1 << (row + col + bk + bw - 20));
|
||||
if (bw == 2) {
|
||||
if (cs_cap <= 0x2000000) /* 256Mb */
|
||||
die_bw_0 = (col < 9) ? 2 : 1;
|
||||
else if (cs_cap <= 0x10000000) /* 2Gb */
|
||||
die_bw_0 = (col < 10) ? 2 : 1;
|
||||
else if (cs_cap <= 0x40000000) /* 8Gb */
|
||||
die_bw_0 = (col < 11) ? 2 : 1;
|
||||
else
|
||||
die_bw_0 = (col < 12) ? 2 : 1;
|
||||
if (cs > 1) {
|
||||
row = cap_info->cs1_row;
|
||||
cs_cap = (1 << (row + col + bk + bw - 20));
|
||||
if (cs_cap <= 0x2000000) /* 256Mb */
|
||||
die_bw_0 = (col < 9) ? 2 : 1;
|
||||
else if (cs_cap <= 0x10000000) /* 2Gb */
|
||||
die_bw_0 = (col < 10) ? 2 : 1;
|
||||
else if (cs_cap <= 0x40000000) /* 8Gb */
|
||||
die_bw_0 = (col < 11) ? 2 : 1;
|
||||
else
|
||||
die_bw_0 = (col < 12) ? 2 : 1;
|
||||
}
|
||||
} else {
|
||||
die_bw_1 = 1;
|
||||
die_bw_0 = 1;
|
||||
}
|
||||
cap_info->dbw = (die_bw_0 > die_bw_1) ? die_bw_0 : die_bw_1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sdram_detect_row(struct sdram_cap_info *cap_info,
|
||||
u32 coltmp, u32 bktmp, u32 rowtmp)
|
||||
{
|
||||
u32 row;
|
||||
u32 bw = cap_info->bw;
|
||||
void __iomem *test_addr;
|
||||
|
||||
for (row = rowtmp; row > 12; row--) {
|
||||
writel(0, CONFIG_SYS_SDRAM_BASE);
|
||||
test_addr = (void __iomem *)(CONFIG_SYS_SDRAM_BASE +
|
||||
(1ul << (row + bktmp + coltmp + bw - 1ul)));
|
||||
writel(PATTERN, test_addr);
|
||||
if ((readl(test_addr) == PATTERN) &&
|
||||
(readl(CONFIG_SYS_SDRAM_BASE) == 0))
|
||||
break;
|
||||
}
|
||||
if (row == 12) {
|
||||
printascii("row error");
|
||||
return -1;
|
||||
}
|
||||
|
||||
cap_info->cs0_row = row;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sdram_detect_row_3_4(struct sdram_cap_info *cap_info,
|
||||
u32 coltmp, u32 bktmp)
|
||||
{
|
||||
u32 row_3_4;
|
||||
u32 bw = cap_info->bw;
|
||||
u32 row = cap_info->cs0_row;
|
||||
void __iomem *test_addr, *test_addr1;
|
||||
|
||||
test_addr = CONFIG_SYS_SDRAM_BASE;
|
||||
test_addr1 = (void __iomem *)(CONFIG_SYS_SDRAM_BASE +
|
||||
(0x3ul << (row + bktmp + coltmp + bw - 1ul - 1ul)));
|
||||
|
||||
writel(0, test_addr);
|
||||
writel(PATTERN, test_addr1);
|
||||
if ((readl(test_addr) == 0) && (readl(test_addr1) == PATTERN))
|
||||
row_3_4 = 0;
|
||||
else
|
||||
row_3_4 = 1;
|
||||
|
||||
cap_info->row_3_4 = row_3_4;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sdram_detect_high_row(struct sdram_cap_info *cap_info)
|
||||
{
|
||||
cap_info->cs0_high16bit_row = cap_info->cs0_row;
|
||||
cap_info->cs1_high16bit_row = cap_info->cs1_row;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sdram_detect_cs1_row(struct sdram_cap_info *cap_info, u32 dram_type)
|
||||
{
|
||||
void __iomem *test_addr;
|
||||
u32 row = 0, bktmp, coltmp, bw;
|
||||
ulong cs0_cap;
|
||||
u32 byte_mask;
|
||||
|
||||
if (cap_info->rank == 2) {
|
||||
cs0_cap = sdram_get_cs_cap(cap_info, 0, dram_type);
|
||||
|
||||
if (dram_type == DDR4) {
|
||||
if (cap_info->dbw == 0)
|
||||
bktmp = cap_info->bk + 2;
|
||||
else
|
||||
bktmp = cap_info->bk + 1;
|
||||
} else {
|
||||
bktmp = cap_info->bk;
|
||||
}
|
||||
bw = cap_info->bw;
|
||||
coltmp = cap_info->col;
|
||||
|
||||
/*
|
||||
* because px30 support axi split,min bandwidth
|
||||
* is 8bit. if cs0 is 32bit, cs1 may 32bit or 16bit
|
||||
* so we check low 16bit data when detect cs1 row.
|
||||
* if cs0 is 16bit/8bit, we check low 8bit data.
|
||||
*/
|
||||
if (bw == 2)
|
||||
byte_mask = 0xFFFF;
|
||||
else
|
||||
byte_mask = 0xFF;
|
||||
|
||||
/* detect cs1 row */
|
||||
for (row = cap_info->cs0_row; row > 12; row--) {
|
||||
test_addr = (void __iomem *)(CONFIG_SYS_SDRAM_BASE +
|
||||
cs0_cap +
|
||||
(1ul << (row + bktmp + coltmp + bw - 1ul)));
|
||||
writel(0, CONFIG_SYS_SDRAM_BASE + cs0_cap);
|
||||
writel(PATTERN, test_addr);
|
||||
|
||||
if (((readl(test_addr) & byte_mask) ==
|
||||
(PATTERN & byte_mask)) &&
|
||||
((readl(CONFIG_SYS_SDRAM_BASE + cs0_cap) &
|
||||
byte_mask) == 0)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cap_info->cs1_row = row;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,205 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* (C) Copyright 2018 Rockchip Electronics Co., Ltd.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <ram.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/arch-rockchip/sdram.h>
|
||||
#include <asm/arch-rockchip/sdram_pctl_px30.h>
|
||||
|
||||
/*
|
||||
* rank = 1: cs0
|
||||
* rank = 2: cs1
|
||||
*/
|
||||
void pctl_read_mr(void __iomem *pctl_base, u32 rank, u32 mr_num)
|
||||
{
|
||||
writel((rank << 4) | (1 << 0), pctl_base + DDR_PCTL2_MRCTRL0);
|
||||
writel((mr_num << 8), pctl_base + DDR_PCTL2_MRCTRL1);
|
||||
setbits_le32(pctl_base + DDR_PCTL2_MRCTRL0, 1u << 31);
|
||||
while (readl(pctl_base + DDR_PCTL2_MRCTRL0) & (1u << 31))
|
||||
continue;
|
||||
while (readl(pctl_base + DDR_PCTL2_MRSTAT) & MR_WR_BUSY)
|
||||
continue;
|
||||
}
|
||||
|
||||
/* rank = 1: cs0
|
||||
* rank = 2: cs1
|
||||
* rank = 3: cs0 & cs1
|
||||
* note: be careful of keep mr original val
|
||||
*/
|
||||
int pctl_write_mr(void __iomem *pctl_base, u32 rank, u32 mr_num, u32 arg,
|
||||
u32 dramtype)
|
||||
{
|
||||
while (readl(pctl_base + DDR_PCTL2_MRSTAT) & MR_WR_BUSY)
|
||||
continue;
|
||||
if (dramtype == DDR3 || dramtype == DDR4) {
|
||||
writel((mr_num << 12) | (rank << 4) | (0 << 0),
|
||||
pctl_base + DDR_PCTL2_MRCTRL0);
|
||||
writel(arg, pctl_base + DDR_PCTL2_MRCTRL1);
|
||||
} else {
|
||||
writel((rank << 4) | (0 << 0),
|
||||
pctl_base + DDR_PCTL2_MRCTRL0);
|
||||
writel((mr_num << 8) | (arg & 0xff),
|
||||
pctl_base + DDR_PCTL2_MRCTRL1);
|
||||
}
|
||||
|
||||
setbits_le32(pctl_base + DDR_PCTL2_MRCTRL0, 1u << 31);
|
||||
while (readl(pctl_base + DDR_PCTL2_MRCTRL0) & (1u << 31))
|
||||
continue;
|
||||
while (readl(pctl_base + DDR_PCTL2_MRSTAT) & MR_WR_BUSY)
|
||||
continue;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* rank : 1:cs0, 2:cs1, 3:cs0&cs1
|
||||
* vrefrate: 4500: 45%,
|
||||
*/
|
||||
int pctl_write_vrefdq(void __iomem *pctl_base, u32 rank, u32 vrefrate,
|
||||
u32 dramtype)
|
||||
{
|
||||
u32 tccd_l, value;
|
||||
u32 dis_auto_zq = 0;
|
||||
|
||||
if (dramtype != DDR4 || vrefrate < 4500 ||
|
||||
vrefrate > 9200)
|
||||
return (-1);
|
||||
|
||||
tccd_l = (readl(pctl_base + DDR_PCTL2_DRAMTMG4) >> 16) & 0xf;
|
||||
tccd_l = (tccd_l - 4) << 10;
|
||||
|
||||
if (vrefrate > 7500) {
|
||||
/* range 1 */
|
||||
value = ((vrefrate - 6000) / 65) | tccd_l;
|
||||
} else {
|
||||
/* range 2 */
|
||||
value = ((vrefrate - 4500) / 65) | tccd_l | (1 << 6);
|
||||
}
|
||||
|
||||
dis_auto_zq = pctl_dis_zqcs_aref(pctl_base);
|
||||
|
||||
/* enable vrefdq calibratin */
|
||||
pctl_write_mr(pctl_base, rank, 6, value | (1 << 7), dramtype);
|
||||
udelay(1);/* tvrefdqe */
|
||||
/* write vrefdq value */
|
||||
pctl_write_mr(pctl_base, rank, 6, value | (1 << 7), dramtype);
|
||||
udelay(1);/* tvref_time */
|
||||
pctl_write_mr(pctl_base, rank, 6, value | (0 << 7), dramtype);
|
||||
udelay(1);/* tvrefdqx */
|
||||
|
||||
pctl_rest_zqcs_aref(pctl_base, dis_auto_zq);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int upctl2_update_ref_reg(void __iomem *pctl_base)
|
||||
{
|
||||
u32 ret;
|
||||
|
||||
ret = readl(pctl_base + DDR_PCTL2_RFSHCTL3) ^ (1 << 1);
|
||||
writel(ret, pctl_base + DDR_PCTL2_RFSHCTL3);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
u32 pctl_dis_zqcs_aref(void __iomem *pctl_base)
|
||||
{
|
||||
u32 dis_auto_zq = 0;
|
||||
|
||||
/* disable zqcs */
|
||||
if (!(readl(pctl_base + DDR_PCTL2_ZQCTL0) &
|
||||
(1ul << 31))) {
|
||||
dis_auto_zq = 1;
|
||||
setbits_le32(pctl_base + DDR_PCTL2_ZQCTL0, 1 << 31);
|
||||
}
|
||||
|
||||
/* disable auto refresh */
|
||||
setbits_le32(pctl_base + DDR_PCTL2_RFSHCTL3, 1);
|
||||
|
||||
upctl2_update_ref_reg(pctl_base);
|
||||
|
||||
return dis_auto_zq;
|
||||
}
|
||||
|
||||
void pctl_rest_zqcs_aref(void __iomem *pctl_base, u32 dis_auto_zq)
|
||||
{
|
||||
/* restore zqcs */
|
||||
if (dis_auto_zq)
|
||||
clrbits_le32(pctl_base + DDR_PCTL2_ZQCTL0, 1 << 31);
|
||||
|
||||
/* restore auto refresh */
|
||||
clrbits_le32(pctl_base + DDR_PCTL2_RFSHCTL3, 1);
|
||||
|
||||
upctl2_update_ref_reg(pctl_base);
|
||||
}
|
||||
|
||||
u32 pctl_remodify_sdram_params(struct ddr_pctl_regs *pctl_regs,
|
||||
struct sdram_cap_info *cap_info,
|
||||
u32 dram_type)
|
||||
{
|
||||
u32 tmp = 0, tmp_adr = 0, i;
|
||||
|
||||
for (i = 0; pctl_regs->pctl[i][0] != 0xFFFFFFFF; i++) {
|
||||
if (pctl_regs->pctl[i][0] == 0) {
|
||||
tmp = pctl_regs->pctl[i][1];/* MSTR */
|
||||
tmp_adr = i;
|
||||
}
|
||||
}
|
||||
|
||||
tmp &= ~((3ul << 30) | (3ul << 24) | (3ul << 12));
|
||||
|
||||
switch (cap_info->dbw) {
|
||||
case 2:
|
||||
tmp |= (3ul << 30);
|
||||
break;
|
||||
case 1:
|
||||
tmp |= (2ul << 30);
|
||||
break;
|
||||
case 0:
|
||||
default:
|
||||
tmp |= (1ul << 30);
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* If DDR3 or DDR4 MSTR.active_ranks=1,
|
||||
* it will gate memory clock when enter power down.
|
||||
* Force set active_ranks to 3 to workaround it.
|
||||
*/
|
||||
if (cap_info->rank == 2 || dram_type == DDR3 ||
|
||||
dram_type == DDR4)
|
||||
tmp |= 3 << 24;
|
||||
else
|
||||
tmp |= 1 << 24;
|
||||
|
||||
tmp |= (2 - cap_info->bw) << 12;
|
||||
|
||||
pctl_regs->pctl[tmp_adr][1] = tmp;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pctl_cfg(void __iomem *pctl_base, struct ddr_pctl_regs *pctl_regs,
|
||||
u32 sr_idle, u32 pd_idle)
|
||||
{
|
||||
u32 i;
|
||||
|
||||
for (i = 0; pctl_regs->pctl[i][0] != 0xFFFFFFFF; i++) {
|
||||
writel(pctl_regs->pctl[i][1],
|
||||
pctl_base + pctl_regs->pctl[i][0]);
|
||||
}
|
||||
clrsetbits_le32(pctl_base + DDR_PCTL2_PWRTMG,
|
||||
(0xff << 16) | 0x1f,
|
||||
((sr_idle & 0xff) << 16) | (pd_idle & 0x1f));
|
||||
|
||||
clrsetbits_le32(pctl_base + DDR_PCTL2_HWLPCTL,
|
||||
0xfff << 16,
|
||||
5 << 16);
|
||||
/* disable zqcs */
|
||||
setbits_le32(pctl_base + DDR_PCTL2_ZQCTL0, 1u << 31);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,205 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* (C) Copyright 2018 Rockchip Electronics Co., Ltd.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <ram.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/arch-rockchip/sdram.h>
|
||||
#include <asm/arch-rockchip/sdram_common.h>
|
||||
#include <asm/arch-rockchip/sdram_phy_px30.h>
|
||||
|
||||
static void sdram_phy_dll_bypass_set(void __iomem *phy_base, u32 freq)
|
||||
{
|
||||
u32 tmp;
|
||||
u32 i, j;
|
||||
u32 dqs_dll_freq;
|
||||
|
||||
setbits_le32(PHY_REG(phy_base, 0x13), 1 << 4);
|
||||
clrbits_le32(PHY_REG(phy_base, 0x14), 1 << 3);
|
||||
for (i = 0; i < 4; i++) {
|
||||
j = 0x26 + i * 0x10;
|
||||
setbits_le32(PHY_REG(phy_base, j), 1 << 4);
|
||||
clrbits_le32(PHY_REG(phy_base, j + 0x1), 1 << 3);
|
||||
}
|
||||
|
||||
if (freq <= 400)
|
||||
/* DLL bypass */
|
||||
setbits_le32(PHY_REG(phy_base, 0xa4), 0x1f);
|
||||
else
|
||||
clrbits_le32(PHY_REG(phy_base, 0xa4), 0x1f);
|
||||
|
||||
#ifdef CONFIG_ROCKCHIP_RK3328
|
||||
dqs_dll_freq = 680;
|
||||
#else
|
||||
dqs_dll_freq = 801;
|
||||
#endif
|
||||
|
||||
if (freq <= dqs_dll_freq)
|
||||
tmp = 2;
|
||||
else
|
||||
tmp = 1;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
j = 0x28 + i * 0x10;
|
||||
writel(tmp, PHY_REG(phy_base, j));
|
||||
}
|
||||
}
|
||||
|
||||
static void sdram_phy_set_ds_odt(void __iomem *phy_base,
|
||||
u32 dram_type)
|
||||
{
|
||||
u32 cmd_drv, clk_drv, dqs_drv, dqs_odt;
|
||||
u32 i, j;
|
||||
|
||||
if (dram_type == DDR3) {
|
||||
cmd_drv = PHY_DDR3_RON_RTT_34ohm;
|
||||
clk_drv = PHY_DDR3_RON_RTT_45ohm;
|
||||
dqs_drv = PHY_DDR3_RON_RTT_34ohm;
|
||||
dqs_odt = PHY_DDR3_RON_RTT_225ohm;
|
||||
} else {
|
||||
cmd_drv = PHY_DDR4_LPDDR3_RON_RTT_34ohm;
|
||||
clk_drv = PHY_DDR4_LPDDR3_RON_RTT_43ohm;
|
||||
dqs_drv = PHY_DDR4_LPDDR3_RON_RTT_34ohm;
|
||||
if (dram_type == LPDDR2)
|
||||
dqs_odt = PHY_DDR4_LPDDR3_RON_RTT_DISABLE;
|
||||
else
|
||||
dqs_odt = PHY_DDR4_LPDDR3_RON_RTT_240ohm;
|
||||
}
|
||||
/* DS */
|
||||
writel(cmd_drv, PHY_REG(phy_base, 0x11));
|
||||
clrsetbits_le32(PHY_REG(phy_base, 0x12), 0x1f << 3, cmd_drv << 3);
|
||||
writel(clk_drv, PHY_REG(phy_base, 0x16));
|
||||
writel(clk_drv, PHY_REG(phy_base, 0x18));
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
j = 0x20 + i * 0x10;
|
||||
writel(dqs_drv, PHY_REG(phy_base, j));
|
||||
writel(dqs_drv, PHY_REG(phy_base, j + 0xf));
|
||||
/* ODT */
|
||||
writel(dqs_odt, PHY_REG(phy_base, j + 0x1));
|
||||
writel(dqs_odt, PHY_REG(phy_base, j + 0xe));
|
||||
}
|
||||
}
|
||||
|
||||
void phy_soft_reset(void __iomem *phy_base)
|
||||
{
|
||||
clrbits_le32(PHY_REG(phy_base, 0), 0x3 << 2);
|
||||
udelay(1);
|
||||
setbits_le32(PHY_REG(phy_base, 0), ANALOG_DERESET);
|
||||
udelay(5);
|
||||
setbits_le32(PHY_REG(phy_base, 0), DIGITAL_DERESET);
|
||||
udelay(1);
|
||||
}
|
||||
|
||||
void phy_dram_set_bw(void __iomem *phy_base, u32 bw)
|
||||
{
|
||||
if (bw == 2) {
|
||||
clrsetbits_le32(PHY_REG(phy_base, 0), 0xf << 4, 0xf << 4);
|
||||
setbits_le32(PHY_REG(phy_base, 0x46), 1 << 3);
|
||||
setbits_le32(PHY_REG(phy_base, 0x56), 1 << 3);
|
||||
} else if (bw == 1) {
|
||||
clrsetbits_le32(PHY_REG(phy_base, 0), 0xf << 4, 3 << 4);
|
||||
clrbits_le32(PHY_REG(phy_base, 0x46), 1 << 3);
|
||||
clrbits_le32(PHY_REG(phy_base, 0x56), 1 << 3);
|
||||
} else if (bw == 0) {
|
||||
clrsetbits_le32(PHY_REG(phy_base, 0), 0xf << 4, 1 << 4);
|
||||
clrbits_le32(PHY_REG(phy_base, 0x36), 1 << 3);
|
||||
clrbits_le32(PHY_REG(phy_base, 0x46), 1 << 3);
|
||||
clrbits_le32(PHY_REG(phy_base, 0x56), 1 << 3);
|
||||
}
|
||||
|
||||
phy_soft_reset(phy_base);
|
||||
}
|
||||
|
||||
int phy_data_training(void __iomem *phy_base, u32 cs, u32 dramtype)
|
||||
{
|
||||
u32 ret;
|
||||
u32 odt_val;
|
||||
u32 i, j;
|
||||
|
||||
odt_val = readl(PHY_REG(phy_base, 0x2e));
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
j = 0x20 + i * 0x10;
|
||||
writel(PHY_DDR3_RON_RTT_225ohm, PHY_REG(phy_base, j + 0x1));
|
||||
writel(0, PHY_REG(phy_base, j + 0xe));
|
||||
}
|
||||
|
||||
if (dramtype == DDR4) {
|
||||
clrsetbits_le32(PHY_REG(phy_base, 0x29), 0x3, 0);
|
||||
clrsetbits_le32(PHY_REG(phy_base, 0x39), 0x3, 0);
|
||||
clrsetbits_le32(PHY_REG(phy_base, 0x49), 0x3, 0);
|
||||
clrsetbits_le32(PHY_REG(phy_base, 0x59), 0x3, 0);
|
||||
}
|
||||
/* choose training cs */
|
||||
clrsetbits_le32(PHY_REG(phy_base, 2), 0x33, (0x20 >> cs));
|
||||
/* enable gate training */
|
||||
clrsetbits_le32(PHY_REG(phy_base, 2), 0x33, (0x20 >> cs) | 1);
|
||||
udelay(50);
|
||||
ret = readl(PHY_REG(phy_base, 0xff));
|
||||
/* disable gate training */
|
||||
clrsetbits_le32(PHY_REG(phy_base, 2), 0x33, (0x20 >> cs) | 0);
|
||||
#ifndef CONFIG_ROCKCHIP_RK3328
|
||||
clrbits_le32(PHY_REG(phy_base, 2), 0x30);
|
||||
#endif
|
||||
|
||||
if (dramtype == DDR4) {
|
||||
clrsetbits_le32(PHY_REG(phy_base, 0x29), 0x3, 0x2);
|
||||
clrsetbits_le32(PHY_REG(phy_base, 0x39), 0x3, 0x2);
|
||||
clrsetbits_le32(PHY_REG(phy_base, 0x49), 0x3, 0x2);
|
||||
clrsetbits_le32(PHY_REG(phy_base, 0x59), 0x3, 0x2);
|
||||
}
|
||||
|
||||
if (ret & 0x10) {
|
||||
ret = -1;
|
||||
} else {
|
||||
ret = (ret & 0xf) ^ (readl(PHY_REG(phy_base, 0)) >> 4);
|
||||
ret = (ret == 0) ? 0 : -1;
|
||||
}
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
j = 0x20 + i * 0x10;
|
||||
writel(odt_val, PHY_REG(phy_base, j + 0x1));
|
||||
writel(odt_val, PHY_REG(phy_base, j + 0xe));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void phy_cfg(void __iomem *phy_base,
|
||||
struct ddr_phy_regs *phy_regs, struct ddr_phy_skew *skew,
|
||||
struct sdram_base_params *base, u32 bw)
|
||||
{
|
||||
u32 i;
|
||||
|
||||
sdram_phy_dll_bypass_set(phy_base, base->ddr_freq);
|
||||
for (i = 0; phy_regs->phy[i][0] != 0xFFFFFFFF; i++) {
|
||||
writel(phy_regs->phy[i][1],
|
||||
phy_base + phy_regs->phy[i][0]);
|
||||
}
|
||||
if (bw == 2) {
|
||||
clrsetbits_le32(PHY_REG(phy_base, 0), 0xf << 4, 0xf << 4);
|
||||
} else if (bw == 1) {
|
||||
clrsetbits_le32(PHY_REG(phy_base, 0), 0xf << 4, 3 << 4);
|
||||
/* disable DQS2,DQS3 tx dll for saving power */
|
||||
clrbits_le32(PHY_REG(phy_base, 0x46), 1 << 3);
|
||||
clrbits_le32(PHY_REG(phy_base, 0x56), 1 << 3);
|
||||
} else {
|
||||
clrsetbits_le32(PHY_REG(phy_base, 0), 0xf << 4, 1 << 4);
|
||||
/* disable DQS2,DQS3 tx dll for saving power */
|
||||
clrbits_le32(PHY_REG(phy_base, 0x36), 1 << 3);
|
||||
clrbits_le32(PHY_REG(phy_base, 0x46), 1 << 3);
|
||||
clrbits_le32(PHY_REG(phy_base, 0x56), 1 << 3);
|
||||
}
|
||||
sdram_phy_set_ds_odt(phy_base, base->dramtype);
|
||||
|
||||
/* deskew */
|
||||
setbits_le32(PHY_REG(phy_base, 2), 8);
|
||||
sdram_copy_to_reg(PHY_REG(phy_base, 0xb0),
|
||||
&skew->a0_a1_skew[0], 15 * 4);
|
||||
sdram_copy_to_reg(PHY_REG(phy_base, 0x70),
|
||||
&skew->cs0_dm0_skew[0], 44 * 4);
|
||||
sdram_copy_to_reg(PHY_REG(phy_base, 0xc0),
|
||||
&skew->cs1_dm0_skew[0], 44 * 4);
|
||||
}
|
||||
@@ -0,0 +1,751 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* (C) Copyright 2018 Rockchip Electronics Co., Ltd.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <debug_uart.h>
|
||||
#include <dm.h>
|
||||
#include <ram.h>
|
||||
#include <syscon.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/arch-rockchip/clock.h>
|
||||
#include <asm/arch-rockchip/cru_px30.h>
|
||||
#include <asm/arch-rockchip/grf_px30.h>
|
||||
#include <asm/arch-rockchip/hardware.h>
|
||||
#include <asm/arch-rockchip/sdram.h>
|
||||
#include <asm/arch-rockchip/sdram_px30.h>
|
||||
|
||||
struct dram_info {
|
||||
#ifdef CONFIG_TPL_BUILD
|
||||
struct ddr_pctl_regs *pctl;
|
||||
struct ddr_phy_regs *phy;
|
||||
struct px30_cru *cru;
|
||||
struct msch_regs *msch;
|
||||
struct px30_ddr_grf_regs *ddr_grf;
|
||||
struct px30_grf *grf;
|
||||
#endif
|
||||
struct ram_info info;
|
||||
struct px30_pmugrf *pmugrf;
|
||||
};
|
||||
|
||||
#ifdef CONFIG_TPL_BUILD
|
||||
|
||||
u8 ddr_cfg_2_rbc[] = {
|
||||
/*
|
||||
* [6:4] max row: 13+n
|
||||
* [3] bank(0:4bank,1:8bank)
|
||||
* [2:0] col(10+n)
|
||||
*/
|
||||
((5 << 4) | (1 << 3) | 0), /* 0 */
|
||||
((5 << 4) | (1 << 3) | 1), /* 1 */
|
||||
((4 << 4) | (1 << 3) | 2), /* 2 */
|
||||
((3 << 4) | (1 << 3) | 3), /* 3 */
|
||||
((2 << 4) | (1 << 3) | 4), /* 4 */
|
||||
((5 << 4) | (0 << 3) | 2), /* 5 */
|
||||
((4 << 4) | (1 << 3) | 2), /* 6 */
|
||||
/*((0<<3)|3),*/ /* 12 for ddr4 */
|
||||
/*((1<<3)|1),*/ /* 13 B,C exchange for rkvdec */
|
||||
};
|
||||
|
||||
/*
|
||||
* for ddr4 if ddrconfig=7, upctl should set 7 and noc should
|
||||
* set to 1 for more efficient.
|
||||
* noc ddrconf, upctl addrmap
|
||||
* 1 7
|
||||
* 2 8
|
||||
* 3 9
|
||||
* 12 10
|
||||
* 5 11
|
||||
*/
|
||||
u8 d4_rbc_2_d3_rbc[] = {
|
||||
1, /* 7 */
|
||||
2, /* 8 */
|
||||
3, /* 9 */
|
||||
12, /* 10 */
|
||||
5, /* 11 */
|
||||
};
|
||||
|
||||
/*
|
||||
* row higher than cs should be disabled by set to 0xf
|
||||
* rank addrmap calculate by real cap.
|
||||
*/
|
||||
u32 addrmap[][8] = {
|
||||
/* map0 map1, map2, map3, map4, map5
|
||||
* map6, map7, map8
|
||||
* -------------------------------------------------------
|
||||
* bk2-0 col 5-2 col 9-6 col 11-10 row 11-0
|
||||
* row 15-12 row 17-16 bg1,0
|
||||
* -------------------------------------------------------
|
||||
* 4,3,2 5-2 9-6 6
|
||||
* 3,2
|
||||
*/
|
||||
{0x00060606, 0x00000000, 0x1f1f0000, 0x00001f1f, 0x05050505,
|
||||
0x05050505, 0x00000505, 0x3f3f}, /* 0 */
|
||||
{0x00070707, 0x00000000, 0x1f000000, 0x00001f1f, 0x06060606,
|
||||
0x06060606, 0x06060606, 0x3f3f}, /* 1 */
|
||||
{0x00080808, 0x00000000, 0x00000000, 0x00001f1f, 0x07070707,
|
||||
0x07070707, 0x00000f07, 0x3f3f}, /* 2 */
|
||||
{0x00090909, 0x00000000, 0x00000000, 0x00001f00, 0x08080808,
|
||||
0x08080808, 0x00000f0f, 0x3f3f}, /* 3 */
|
||||
{0x000a0a0a, 0x00000000, 0x00000000, 0x00000000, 0x09090909,
|
||||
0x0f090909, 0x00000f0f, 0x3f3f}, /* 4 */
|
||||
{0x00080808, 0x00000000, 0x00000000, 0x00001f1f, 0x06060606,
|
||||
0x06060606, 0x00000606, 0x3f3f}, /* 5 */
|
||||
{0x00080808, 0x00000000, 0x00000000, 0x00001f1f, 0x07070707,
|
||||
0x07070707, 0x00000f0f, 0x3f3f}, /* 6 */
|
||||
{0x003f0808, 0x00000006, 0x1f1f0000, 0x00001f1f, 0x06060606,
|
||||
0x06060606, 0x00000606, 0x0600}, /* 7 */
|
||||
{0x003f0909, 0x00000007, 0x1f000000, 0x00001f1f, 0x07070707,
|
||||
0x07070707, 0x00000f07, 0x0700}, /* 8 */
|
||||
{0x003f0a0a, 0x01010100, 0x01010101, 0x00001f1f, 0x08080808,
|
||||
0x08080808, 0x00000f0f, 0x0801}, /* 9 */
|
||||
{0x003f0909, 0x01010100, 0x01010101, 0x00001f1f, 0x07070707,
|
||||
0x07070707, 0x00000f07, 0x3f01}, /* 10 */
|
||||
{0x003f0808, 0x00000007, 0x1f000000, 0x00001f1f, 0x06060606,
|
||||
0x06060606, 0x00000606, 0x3f00}, /* 11 */
|
||||
/* when ddr4 12 map to 10, when ddr3 12 unused */
|
||||
{0x003f0909, 0x01010100, 0x01010101, 0x00001f1f, 0x07070707,
|
||||
0x07070707, 0x00000f07, 0x3f01}, /* 10 */
|
||||
{0x00070706, 0x00000000, 0x1f010000, 0x00001f1f, 0x06060606,
|
||||
0x06060606, 0x00000606, 0x3f3f}, /* 13 */
|
||||
};
|
||||
|
||||
#define PMUGRF_BASE_ADDR 0xFF010000
|
||||
#define CRU_BASE_ADDR 0xFF2B0000
|
||||
#define GRF_BASE_ADDR 0xFF140000
|
||||
#define DDRC_BASE_ADDR 0xFF600000
|
||||
#define DDR_PHY_BASE_ADDR 0xFF2A0000
|
||||
#define SERVER_MSCH0_BASE_ADDR 0xFF530000
|
||||
#define DDR_GRF_BASE_ADDR 0xff630000
|
||||
|
||||
struct dram_info dram_info;
|
||||
|
||||
struct px30_sdram_params sdram_configs[] = {
|
||||
#include "sdram-px30-ddr3-detect-333.inc"
|
||||
};
|
||||
|
||||
struct ddr_phy_skew skew = {
|
||||
#include "sdram-px30-ddr_skew.inc"
|
||||
};
|
||||
|
||||
static void rkclk_ddr_reset(struct dram_info *dram,
|
||||
u32 ctl_srstn, u32 ctl_psrstn,
|
||||
u32 phy_srstn, u32 phy_psrstn)
|
||||
{
|
||||
writel(upctl2_srstn_req(ctl_srstn) | upctl2_psrstn_req(ctl_psrstn) |
|
||||
upctl2_asrstn_req(ctl_srstn),
|
||||
&dram->cru->softrst_con[1]);
|
||||
writel(ddrphy_srstn_req(phy_srstn) | ddrphy_psrstn_req(phy_psrstn),
|
||||
&dram->cru->softrst_con[2]);
|
||||
}
|
||||
|
||||
static void rkclk_set_dpll(struct dram_info *dram, unsigned int hz)
|
||||
{
|
||||
unsigned int refdiv, postdiv1, postdiv2, fbdiv;
|
||||
int delay = 1000;
|
||||
u32 mhz = hz / MHz;
|
||||
|
||||
refdiv = 1;
|
||||
if (mhz <= 300) {
|
||||
postdiv1 = 4;
|
||||
postdiv2 = 2;
|
||||
} else if (mhz <= 400) {
|
||||
postdiv1 = 6;
|
||||
postdiv2 = 1;
|
||||
} else if (mhz <= 600) {
|
||||
postdiv1 = 4;
|
||||
postdiv2 = 1;
|
||||
} else if (mhz <= 800) {
|
||||
postdiv1 = 3;
|
||||
postdiv2 = 1;
|
||||
} else if (mhz <= 1600) {
|
||||
postdiv1 = 2;
|
||||
postdiv2 = 1;
|
||||
} else {
|
||||
postdiv1 = 1;
|
||||
postdiv2 = 1;
|
||||
}
|
||||
fbdiv = (mhz * refdiv * postdiv1 * postdiv2) / 24;
|
||||
|
||||
writel(DPLL_MODE(CLOCK_FROM_XIN_OSC), &dram->cru->mode);
|
||||
|
||||
writel(POSTDIV1(postdiv1) | FBDIV(fbdiv), &dram->cru->pll[1].con0);
|
||||
writel(DSMPD(1) | POSTDIV2(postdiv2) | REFDIV(refdiv),
|
||||
&dram->cru->pll[1].con1);
|
||||
|
||||
while (delay > 0) {
|
||||
udelay(1);
|
||||
if (LOCK(readl(&dram->cru->pll[1].con1)))
|
||||
break;
|
||||
delay--;
|
||||
}
|
||||
|
||||
writel(DPLL_MODE(CLOCK_FROM_PLL), &dram->cru->mode);
|
||||
}
|
||||
|
||||
static void rkclk_configure_ddr(struct dram_info *dram,
|
||||
struct px30_sdram_params *sdram_params)
|
||||
{
|
||||
/* for inno ddr phy need 2*freq */
|
||||
rkclk_set_dpll(dram, sdram_params->base.ddr_freq * MHz * 2);
|
||||
}
|
||||
|
||||
/* return ddrconfig value
|
||||
* (-1), find ddrconfig fail
|
||||
* other, the ddrconfig value
|
||||
* only support cs0_row >= cs1_row
|
||||
*/
|
||||
static unsigned int calculate_ddrconfig(struct px30_sdram_params *sdram_params)
|
||||
{
|
||||
struct sdram_cap_info *cap_info = &sdram_params->ch.cap_info;
|
||||
u32 bw, die_bw, col, bank;
|
||||
u32 i, tmp;
|
||||
u32 ddrconf = -1;
|
||||
|
||||
bw = cap_info->bw;
|
||||
die_bw = cap_info->dbw;
|
||||
col = cap_info->col;
|
||||
bank = cap_info->bk;
|
||||
|
||||
if (sdram_params->base.dramtype == DDR4) {
|
||||
if (die_bw == 0)
|
||||
ddrconf = 7 + bw;
|
||||
else
|
||||
ddrconf = 12 - bw;
|
||||
ddrconf = d4_rbc_2_d3_rbc[ddrconf - 7];
|
||||
} else {
|
||||
tmp = ((bank - 2) << 3) | (col + bw - 10);
|
||||
for (i = 0; i < 7; i++)
|
||||
if ((ddr_cfg_2_rbc[i] & 0xf) == tmp) {
|
||||
ddrconf = i;
|
||||
break;
|
||||
}
|
||||
if (i > 6)
|
||||
printascii("calculate ddrconfig error\n");
|
||||
}
|
||||
|
||||
return ddrconf;
|
||||
}
|
||||
|
||||
/*
|
||||
* calculate controller dram address map, and setting to register.
|
||||
* argument sdram_params->ch.ddrconf must be right value before
|
||||
* call this function.
|
||||
*/
|
||||
static void set_ctl_address_map(struct dram_info *dram,
|
||||
struct px30_sdram_params *sdram_params)
|
||||
{
|
||||
struct sdram_cap_info *cap_info = &sdram_params->ch.cap_info;
|
||||
void __iomem *pctl_base = dram->pctl;
|
||||
u32 cs_pst, bg, max_row, ddrconf;
|
||||
u32 i;
|
||||
|
||||
if (sdram_params->base.dramtype == DDR4)
|
||||
/*
|
||||
* DDR4 8bit dram BG = 2(4bank groups),
|
||||
* 16bit dram BG = 1 (2 bank groups)
|
||||
*/
|
||||
bg = (cap_info->dbw == 0) ? 2 : 1;
|
||||
else
|
||||
bg = 0;
|
||||
|
||||
cs_pst = cap_info->bw + cap_info->col +
|
||||
bg + cap_info->bk + cap_info->cs0_row;
|
||||
if (cs_pst >= 32 || cap_info->rank == 1)
|
||||
writel(0x1f, pctl_base + DDR_PCTL2_ADDRMAP0);
|
||||
else
|
||||
writel(cs_pst - 8, pctl_base + DDR_PCTL2_ADDRMAP0);
|
||||
|
||||
ddrconf = cap_info->ddrconfig;
|
||||
if (sdram_params->base.dramtype == DDR4) {
|
||||
for (i = 0; i < ARRAY_SIZE(d4_rbc_2_d3_rbc); i++) {
|
||||
if (d4_rbc_2_d3_rbc[i] == ddrconf) {
|
||||
ddrconf = 7 + i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sdram_copy_to_reg((u32 *)(pctl_base + DDR_PCTL2_ADDRMAP1),
|
||||
&addrmap[ddrconf][0], 8 * 4);
|
||||
max_row = cs_pst - 1 - 8 - (addrmap[ddrconf][5] & 0xf);
|
||||
|
||||
if (max_row < 12)
|
||||
printascii("set addrmap fail\n");
|
||||
/* need to disable row ahead of rank by set to 0xf */
|
||||
for (i = 17; i > max_row; i--)
|
||||
clrsetbits_le32(pctl_base + DDR_PCTL2_ADDRMAP6 +
|
||||
((i - 12) * 8 / 32) * 4,
|
||||
0xf << ((i - 12) * 8 % 32),
|
||||
0xf << ((i - 12) * 8 % 32));
|
||||
|
||||
if ((sdram_params->base.dramtype == LPDDR3 ||
|
||||
sdram_params->base.dramtype == LPDDR2) &&
|
||||
cap_info->row_3_4)
|
||||
setbits_le32(pctl_base + DDR_PCTL2_ADDRMAP6, 1 << 31);
|
||||
if (sdram_params->base.dramtype == DDR4 && cap_info->bw != 0x2)
|
||||
setbits_le32(pctl_base + DDR_PCTL2_PCCFG, 1 << 8);
|
||||
}
|
||||
|
||||
/*
|
||||
* rank = 1: cs0
|
||||
* rank = 2: cs1
|
||||
*/
|
||||
int read_mr(struct dram_info *dram, u32 rank, u32 mr_num)
|
||||
{
|
||||
void __iomem *ddr_grf_base = dram->ddr_grf;
|
||||
|
||||
pctl_read_mr(dram->pctl, rank, mr_num);
|
||||
|
||||
return (readl(ddr_grf_base + DDR_GRF_STATUS(0)) & 0xff);
|
||||
}
|
||||
|
||||
#define MIN(a, b) (((a) > (b)) ? (b) : (a))
|
||||
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
|
||||
static u32 check_rd_gate(struct dram_info *dram)
|
||||
{
|
||||
void __iomem *phy_base = dram->phy;
|
||||
|
||||
u32 max_val = 0;
|
||||
u32 min_val = 0xff;
|
||||
u32 gate[4];
|
||||
u32 i, bw;
|
||||
|
||||
bw = (readl(PHY_REG(phy_base, 0x0)) >> 4) & 0xf;
|
||||
switch (bw) {
|
||||
case 0x1:
|
||||
bw = 1;
|
||||
break;
|
||||
case 0x3:
|
||||
bw = 2;
|
||||
break;
|
||||
case 0xf:
|
||||
default:
|
||||
bw = 4;
|
||||
break;
|
||||
}
|
||||
|
||||
for (i = 0; i < bw; i++) {
|
||||
gate[i] = readl(PHY_REG(phy_base, 0xfb + i));
|
||||
max_val = MAX(max_val, gate[i]);
|
||||
min_val = MIN(min_val, gate[i]);
|
||||
}
|
||||
|
||||
if (max_val > 0x80 || min_val < 0x20)
|
||||
return -1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int data_training(struct dram_info *dram, u32 cs, u32 dramtype)
|
||||
{
|
||||
void __iomem *pctl_base = dram->pctl;
|
||||
u32 dis_auto_zq = 0;
|
||||
u32 pwrctl;
|
||||
u32 ret;
|
||||
|
||||
/* disable auto low-power */
|
||||
pwrctl = readl(pctl_base + DDR_PCTL2_PWRCTL);
|
||||
writel(0, pctl_base + DDR_PCTL2_PWRCTL);
|
||||
|
||||
dis_auto_zq = pctl_dis_zqcs_aref(dram->pctl);
|
||||
|
||||
ret = phy_data_training(dram->phy, cs, dramtype);
|
||||
|
||||
pctl_rest_zqcs_aref(dram->pctl, dis_auto_zq);
|
||||
|
||||
/* restore auto low-power */
|
||||
writel(pwrctl, pctl_base + DDR_PCTL2_PWRCTL);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void dram_set_bw(struct dram_info *dram, u32 bw)
|
||||
{
|
||||
phy_dram_set_bw(dram->phy, bw);
|
||||
}
|
||||
|
||||
static void set_ddrconfig(struct dram_info *dram, u32 ddrconfig)
|
||||
{
|
||||
writel(ddrconfig | (ddrconfig << 8), &dram->msch->deviceconf);
|
||||
rk_clrsetreg(&dram->grf->soc_noc_con[1], 0x3 << 14, 0 << 14);
|
||||
}
|
||||
|
||||
static void sdram_msch_config(struct msch_regs *msch,
|
||||
struct sdram_msch_timings *noc_timings,
|
||||
struct sdram_cap_info *cap_info,
|
||||
struct sdram_base_params *base)
|
||||
{
|
||||
u64 cs_cap[2];
|
||||
|
||||
cs_cap[0] = sdram_get_cs_cap(cap_info, 0, base->dramtype);
|
||||
cs_cap[1] = sdram_get_cs_cap(cap_info, 1, base->dramtype);
|
||||
writel(((((cs_cap[1] >> 20) / 64) & 0xff) << 8) |
|
||||
(((cs_cap[0] >> 20) / 64) & 0xff),
|
||||
&msch->devicesize);
|
||||
|
||||
writel(noc_timings->ddrtiminga0.d32,
|
||||
&msch->ddrtiminga0);
|
||||
writel(noc_timings->ddrtimingb0.d32,
|
||||
&msch->ddrtimingb0);
|
||||
writel(noc_timings->ddrtimingc0.d32,
|
||||
&msch->ddrtimingc0);
|
||||
writel(noc_timings->devtodev0.d32,
|
||||
&msch->devtodev0);
|
||||
writel(noc_timings->ddrmode.d32, &msch->ddrmode);
|
||||
writel(noc_timings->ddr4timing.d32,
|
||||
&msch->ddr4timing);
|
||||
writel(noc_timings->agingx0, &msch->agingx0);
|
||||
writel(noc_timings->agingx0, &msch->aging0);
|
||||
writel(noc_timings->agingx0, &msch->aging1);
|
||||
writel(noc_timings->agingx0, &msch->aging2);
|
||||
writel(noc_timings->agingx0, &msch->aging3);
|
||||
}
|
||||
|
||||
static void dram_all_config(struct dram_info *dram,
|
||||
struct px30_sdram_params *sdram_params)
|
||||
{
|
||||
struct sdram_cap_info *cap_info = &sdram_params->ch.cap_info;
|
||||
u32 sys_reg2 = 0;
|
||||
u32 sys_reg3 = 0;
|
||||
|
||||
set_ddrconfig(dram, cap_info->ddrconfig);
|
||||
sdram_org_config(cap_info, &sdram_params->base, &sys_reg2,
|
||||
&sys_reg3, 0);
|
||||
writel(sys_reg2, &dram->pmugrf->os_reg[2]);
|
||||
writel(sys_reg3, &dram->pmugrf->os_reg[3]);
|
||||
sdram_msch_config(dram->msch, &sdram_params->ch.noc_timings, cap_info,
|
||||
&sdram_params->base);
|
||||
}
|
||||
|
||||
static void enable_low_power(struct dram_info *dram,
|
||||
struct px30_sdram_params *sdram_params)
|
||||
{
|
||||
void __iomem *pctl_base = dram->pctl;
|
||||
void __iomem *phy_base = dram->phy;
|
||||
void __iomem *ddr_grf_base = dram->ddr_grf;
|
||||
u32 grf_lp_con;
|
||||
|
||||
/*
|
||||
* bit0: grf_upctl_axi_cg_en = 1 enable upctl2 axi clk auto gating
|
||||
* bit1: grf_upctl_apb_cg_en = 1 ungated axi,core clk for apb access
|
||||
* bit2: grf_upctl_core_cg_en = 1 enable upctl2 core clk auto gating
|
||||
* bit3: grf_selfref_type2_en = 0 disable core clk gating when type2 sr
|
||||
* bit4: grf_upctl_syscreq_cg_en = 1
|
||||
* ungating coreclk when c_sysreq assert
|
||||
* bit8-11: grf_auto_sr_dly = 6
|
||||
*/
|
||||
writel(0x1f1f0617, &dram->ddr_grf->ddr_grf_con[1]);
|
||||
|
||||
if (sdram_params->base.dramtype == DDR4)
|
||||
grf_lp_con = (0x7 << 16) | (1 << 1);
|
||||
else if (sdram_params->base.dramtype == DDR3)
|
||||
grf_lp_con = (0x7 << 16) | (1 << 0);
|
||||
else
|
||||
grf_lp_con = (0x7 << 16) | (1 << 2);
|
||||
|
||||
/* en lpckdis_en */
|
||||
grf_lp_con = grf_lp_con | (0x1 << (9 + 16)) | (0x1 << 9);
|
||||
writel(grf_lp_con, ddr_grf_base + DDR_GRF_LP_CON);
|
||||
|
||||
/* off digit module clock when enter power down */
|
||||
setbits_le32(PHY_REG(phy_base, 7), 1 << 7);
|
||||
|
||||
/* enable sr, pd */
|
||||
if (PD_IDLE == 0)
|
||||
clrbits_le32(pctl_base + DDR_PCTL2_PWRCTL, (1 << 1));
|
||||
else
|
||||
setbits_le32(pctl_base + DDR_PCTL2_PWRCTL, (1 << 1));
|
||||
if (SR_IDLE == 0)
|
||||
clrbits_le32(pctl_base + DDR_PCTL2_PWRCTL, 1);
|
||||
else
|
||||
setbits_le32(pctl_base + DDR_PCTL2_PWRCTL, 1);
|
||||
setbits_le32(pctl_base + DDR_PCTL2_PWRCTL, (1 << 3));
|
||||
}
|
||||
|
||||
/*
|
||||
* pre_init: 0: pre init for dram cap detect
|
||||
* 1: detect correct cap(except cs1 row)info, than reinit
|
||||
* 2: after reinit, we detect cs1_row, if cs1_row not equal
|
||||
* to cs0_row and cs is in middle on ddrconf map, we need
|
||||
* to reinit dram, than set the correct ddrconf.
|
||||
*/
|
||||
static int sdram_init_(struct dram_info *dram,
|
||||
struct px30_sdram_params *sdram_params, u32 pre_init)
|
||||
{
|
||||
struct sdram_cap_info *cap_info = &sdram_params->ch.cap_info;
|
||||
void __iomem *pctl_base = dram->pctl;
|
||||
|
||||
rkclk_ddr_reset(dram, 1, 1, 1, 1);
|
||||
udelay(10);
|
||||
/*
|
||||
* dereset ddr phy psrstn to config pll,
|
||||
* if using phy pll psrstn must be dereset
|
||||
* before config pll
|
||||
*/
|
||||
rkclk_ddr_reset(dram, 1, 1, 1, 0);
|
||||
rkclk_configure_ddr(dram, sdram_params);
|
||||
|
||||
/* release phy srst to provide clk to ctrl */
|
||||
rkclk_ddr_reset(dram, 1, 1, 0, 0);
|
||||
udelay(10);
|
||||
phy_soft_reset(dram->phy);
|
||||
/* release ctrl presetn, and config ctl registers */
|
||||
rkclk_ddr_reset(dram, 1, 0, 0, 0);
|
||||
pctl_cfg(dram->pctl, &sdram_params->pctl_regs, SR_IDLE, PD_IDLE);
|
||||
cap_info->ddrconfig = calculate_ddrconfig(sdram_params);
|
||||
set_ctl_address_map(dram, sdram_params);
|
||||
phy_cfg(dram->phy, &sdram_params->phy_regs, sdram_params->skew,
|
||||
&sdram_params->base, cap_info->bw);
|
||||
|
||||
/* enable dfi_init_start to init phy after ctl srstn deassert */
|
||||
setbits_le32(pctl_base + DDR_PCTL2_DFIMISC, (1 << 5) | (1 << 4));
|
||||
|
||||
rkclk_ddr_reset(dram, 0, 0, 0, 0);
|
||||
/* wait for dfi_init_done and dram init complete */
|
||||
while ((readl(pctl_base + DDR_PCTL2_STAT) & 0x7) == 0)
|
||||
continue;
|
||||
|
||||
if (sdram_params->base.dramtype == LPDDR3)
|
||||
pctl_write_mr(dram->pctl, 3, 11, 3, LPDDR3);
|
||||
|
||||
/* do ddr gate training */
|
||||
redo_cs0_training:
|
||||
if (data_training(dram, 0, sdram_params->base.dramtype) != 0) {
|
||||
if (pre_init != 0)
|
||||
printascii("DTT cs0 error\n");
|
||||
return -1;
|
||||
}
|
||||
if (check_rd_gate(dram)) {
|
||||
printascii("re training cs0");
|
||||
goto redo_cs0_training;
|
||||
}
|
||||
|
||||
if (sdram_params->base.dramtype == LPDDR3) {
|
||||
if ((read_mr(dram, 1, 8) & 0x3) != 0x3)
|
||||
return -1;
|
||||
} else if (sdram_params->base.dramtype == LPDDR2) {
|
||||
if ((read_mr(dram, 1, 8) & 0x3) != 0x0)
|
||||
return -1;
|
||||
}
|
||||
/* for px30: when 2cs, both 2 cs should be training */
|
||||
if (pre_init != 0 && cap_info->rank == 2) {
|
||||
redo_cs1_training:
|
||||
if (data_training(dram, 1, sdram_params->base.dramtype) != 0) {
|
||||
printascii("DTT cs1 error\n");
|
||||
return -1;
|
||||
}
|
||||
if (check_rd_gate(dram)) {
|
||||
printascii("re training cs1");
|
||||
goto redo_cs1_training;
|
||||
}
|
||||
}
|
||||
|
||||
if (sdram_params->base.dramtype == DDR4)
|
||||
pctl_write_vrefdq(dram->pctl, 0x3, 5670,
|
||||
sdram_params->base.dramtype);
|
||||
|
||||
dram_all_config(dram, sdram_params);
|
||||
enable_low_power(dram, sdram_params);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dram_detect_cap(struct dram_info *dram,
|
||||
struct px30_sdram_params *sdram_params,
|
||||
unsigned char channel)
|
||||
{
|
||||
struct sdram_cap_info *cap_info = &sdram_params->ch.cap_info;
|
||||
|
||||
/*
|
||||
* for ddr3: ddrconf = 3
|
||||
* for ddr4: ddrconf = 12
|
||||
* for lpddr3: ddrconf = 3
|
||||
* default bw = 1
|
||||
*/
|
||||
u32 bk, bktmp;
|
||||
u32 col, coltmp;
|
||||
u32 rowtmp;
|
||||
u32 cs;
|
||||
u32 bw = 1;
|
||||
u32 dram_type = sdram_params->base.dramtype;
|
||||
|
||||
if (dram_type != DDR4) {
|
||||
/* detect col and bk for ddr3/lpddr3 */
|
||||
coltmp = 12;
|
||||
bktmp = 3;
|
||||
if (dram_type == LPDDR2)
|
||||
rowtmp = 15;
|
||||
else
|
||||
rowtmp = 16;
|
||||
|
||||
if (sdram_detect_col(cap_info, coltmp) != 0)
|
||||
goto cap_err;
|
||||
sdram_detect_bank(cap_info, coltmp, bktmp);
|
||||
sdram_detect_dbw(cap_info, dram_type);
|
||||
} else {
|
||||
/* detect bg for ddr4 */
|
||||
coltmp = 10;
|
||||
bktmp = 4;
|
||||
rowtmp = 17;
|
||||
|
||||
col = 10;
|
||||
bk = 2;
|
||||
cap_info->col = col;
|
||||
cap_info->bk = bk;
|
||||
sdram_detect_bg(cap_info, coltmp);
|
||||
}
|
||||
|
||||
/* detect row */
|
||||
if (sdram_detect_row(cap_info, coltmp, bktmp, rowtmp) != 0)
|
||||
goto cap_err;
|
||||
|
||||
/* detect row_3_4 */
|
||||
sdram_detect_row_3_4(cap_info, coltmp, bktmp);
|
||||
|
||||
/* bw and cs detect using data training */
|
||||
if (data_training(dram, 1, dram_type) == 0)
|
||||
cs = 1;
|
||||
else
|
||||
cs = 0;
|
||||
cap_info->rank = cs + 1;
|
||||
|
||||
dram_set_bw(dram, 2);
|
||||
if (data_training(dram, 0, dram_type) == 0)
|
||||
bw = 2;
|
||||
else
|
||||
bw = 1;
|
||||
cap_info->bw = bw;
|
||||
|
||||
cap_info->cs0_high16bit_row = cap_info->cs0_row;
|
||||
if (cs) {
|
||||
cap_info->cs1_row = cap_info->cs0_row;
|
||||
cap_info->cs1_high16bit_row = cap_info->cs0_row;
|
||||
} else {
|
||||
cap_info->cs1_row = 0;
|
||||
cap_info->cs1_high16bit_row = 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
cap_err:
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* return: 0 = success, other = fail */
|
||||
static int sdram_init_detect(struct dram_info *dram,
|
||||
struct px30_sdram_params *sdram_params)
|
||||
{
|
||||
struct sdram_cap_info *cap_info = &sdram_params->ch.cap_info;
|
||||
u32 ret;
|
||||
u32 sys_reg = 0;
|
||||
u32 sys_reg3 = 0;
|
||||
|
||||
if (sdram_init_(dram, sdram_params, 0) != 0)
|
||||
return -1;
|
||||
|
||||
if (dram_detect_cap(dram, sdram_params, 0) != 0)
|
||||
return -1;
|
||||
|
||||
/* modify bw, cs related timing */
|
||||
pctl_remodify_sdram_params(&sdram_params->pctl_regs, cap_info,
|
||||
sdram_params->base.dramtype);
|
||||
/* reinit sdram by real dram cap */
|
||||
ret = sdram_init_(dram, sdram_params, 1);
|
||||
if (ret != 0)
|
||||
goto out;
|
||||
|
||||
/* redetect cs1 row */
|
||||
sdram_detect_cs1_row(cap_info, sdram_params->base.dramtype);
|
||||
if (cap_info->cs1_row) {
|
||||
sys_reg = readl(&dram->pmugrf->os_reg[2]);
|
||||
sys_reg3 = readl(&dram->pmugrf->os_reg[3]);
|
||||
SYS_REG_ENC_CS1_ROW(cap_info->cs1_row,
|
||||
sys_reg, sys_reg3, 0);
|
||||
writel(sys_reg, &dram->pmugrf->os_reg[2]);
|
||||
writel(sys_reg3, &dram->pmugrf->os_reg[3]);
|
||||
}
|
||||
|
||||
ret = sdram_detect_high_row(cap_info);
|
||||
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct px30_sdram_params
|
||||
*get_default_sdram_config(void)
|
||||
{
|
||||
sdram_configs[0].skew = &skew;
|
||||
|
||||
return &sdram_configs[0];
|
||||
}
|
||||
|
||||
/* return: 0 = success, other = fail */
|
||||
int sdram_init(void)
|
||||
{
|
||||
struct px30_sdram_params *sdram_params;
|
||||
int ret = 0;
|
||||
|
||||
dram_info.phy = (void *)DDR_PHY_BASE_ADDR;
|
||||
dram_info.pctl = (void *)DDRC_BASE_ADDR;
|
||||
dram_info.grf = (void *)GRF_BASE_ADDR;
|
||||
dram_info.cru = (void *)CRU_BASE_ADDR;
|
||||
dram_info.msch = (void *)SERVER_MSCH0_BASE_ADDR;
|
||||
dram_info.ddr_grf = (void *)DDR_GRF_BASE_ADDR;
|
||||
dram_info.pmugrf = (void *)PMUGRF_BASE_ADDR;
|
||||
|
||||
sdram_params = get_default_sdram_config();
|
||||
ret = sdram_init_detect(&dram_info, sdram_params);
|
||||
|
||||
if (ret)
|
||||
goto error;
|
||||
|
||||
sdram_print_ddr_info(&sdram_params->ch.cap_info, &sdram_params->base);
|
||||
|
||||
printascii("out\n");
|
||||
return ret;
|
||||
error:
|
||||
return (-1);
|
||||
}
|
||||
#else
|
||||
|
||||
static int px30_dmc_probe(struct udevice *dev)
|
||||
{
|
||||
struct dram_info *priv = dev_get_priv(dev);
|
||||
|
||||
priv->pmugrf = syscon_get_first_range(ROCKCHIP_SYSCON_PMUGRF);
|
||||
debug("%s: grf=%p\n", __func__, priv->pmugrf);
|
||||
priv->info.base = CONFIG_SYS_SDRAM_BASE;
|
||||
priv->info.size =
|
||||
rockchip_sdram_size((phys_addr_t)&priv->pmugrf->os_reg[2]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int px30_dmc_get_info(struct udevice *dev, struct ram_info *info)
|
||||
{
|
||||
struct dram_info *priv = dev_get_priv(dev);
|
||||
|
||||
*info = priv->info;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct ram_ops px30_dmc_ops = {
|
||||
.get_info = px30_dmc_get_info,
|
||||
};
|
||||
|
||||
static const struct udevice_id px30_dmc_ids[] = {
|
||||
{ .compatible = "rockchip,px30-dmc" },
|
||||
{ }
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(dmc_px30) = {
|
||||
.name = "rockchip_px30_dmc",
|
||||
.id = UCLASS_RAM,
|
||||
.of_match = px30_dmc_ids,
|
||||
.ops = &px30_dmc_ops,
|
||||
.probe = px30_dmc_probe,
|
||||
.priv_auto_alloc_size = sizeof(struct dram_info),
|
||||
};
|
||||
#endif /* CONFIG_TPL_BUILD */
|
||||
@@ -0,0 +1,57 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
|
||||
/*
|
||||
* (C) Copyright 2017 Rockchip Electronics Co., Ltd.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <ram.h>
|
||||
#include <syscon.h>
|
||||
#include <asm/arch-rockchip/clock.h>
|
||||
#include <asm/arch-rockchip/grf_rk3128.h>
|
||||
#include <asm/arch-rockchip/sdram.h>
|
||||
|
||||
struct dram_info {
|
||||
struct ram_info info;
|
||||
struct rk3128_grf *grf;
|
||||
};
|
||||
|
||||
static int rk3128_dmc_probe(struct udevice *dev)
|
||||
{
|
||||
struct dram_info *priv = dev_get_priv(dev);
|
||||
|
||||
priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
|
||||
debug("%s: grf=%p\n", __func__, priv->grf);
|
||||
priv->info.base = CONFIG_SYS_SDRAM_BASE;
|
||||
priv->info.size = rockchip_sdram_size(
|
||||
(phys_addr_t)&priv->grf->os_reg[1]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rk3128_dmc_get_info(struct udevice *dev, struct ram_info *info)
|
||||
{
|
||||
struct dram_info *priv = dev_get_priv(dev);
|
||||
|
||||
*info = priv->info;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct ram_ops rk3128_dmc_ops = {
|
||||
.get_info = rk3128_dmc_get_info,
|
||||
};
|
||||
|
||||
static const struct udevice_id rk3128_dmc_ids[] = {
|
||||
{ .compatible = "rockchip,rk3128-dmc" },
|
||||
{ }
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(dmc_rk3128) = {
|
||||
.name = "rockchip_rk3128_dmc",
|
||||
.id = UCLASS_RAM,
|
||||
.of_match = rk3128_dmc_ids,
|
||||
.ops = &rk3128_dmc_ops,
|
||||
.probe = rk3128_dmc_probe,
|
||||
.priv_auto_alloc_size = sizeof(struct dram_info),
|
||||
};
|
||||
@@ -0,0 +1,957 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
|
||||
/*
|
||||
* (C) Copyright 2015 Google, Inc
|
||||
* Copyright 2014 Rockchip Inc.
|
||||
*
|
||||
* Adapted from the very similar rk3288 ddr init.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <clk.h>
|
||||
#include <dm.h>
|
||||
#include <dt-structs.h>
|
||||
#include <errno.h>
|
||||
#include <ram.h>
|
||||
#include <regmap.h>
|
||||
#include <syscon.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/arch-rockchip/clock.h>
|
||||
#include <asm/arch-rockchip/cru_rk3188.h>
|
||||
#include <asm/arch-rockchip/ddr_rk3188.h>
|
||||
#include <asm/arch-rockchip/grf_rk3188.h>
|
||||
#include <asm/arch-rockchip/pmu_rk3188.h>
|
||||
#include <asm/arch-rockchip/sdram.h>
|
||||
#include <asm/arch-rockchip/sdram_rk3288.h>
|
||||
#include <linux/err.h>
|
||||
|
||||
struct chan_info {
|
||||
struct rk3288_ddr_pctl *pctl;
|
||||
struct rk3288_ddr_publ *publ;
|
||||
struct rk3188_msch *msch;
|
||||
};
|
||||
|
||||
struct dram_info {
|
||||
struct chan_info chan[1];
|
||||
struct ram_info info;
|
||||
struct clk ddr_clk;
|
||||
struct rk3188_cru *cru;
|
||||
struct rk3188_grf *grf;
|
||||
struct rk3188_sgrf *sgrf;
|
||||
struct rk3188_pmu *pmu;
|
||||
};
|
||||
|
||||
struct rk3188_sdram_params {
|
||||
#if CONFIG_IS_ENABLED(OF_PLATDATA)
|
||||
struct dtd_rockchip_rk3188_dmc of_plat;
|
||||
#endif
|
||||
struct rk3288_sdram_channel ch[2];
|
||||
struct rk3288_sdram_pctl_timing pctl_timing;
|
||||
struct rk3288_sdram_phy_timing phy_timing;
|
||||
struct rk3288_base_params base;
|
||||
int num_channels;
|
||||
struct regmap *map;
|
||||
};
|
||||
|
||||
const int ddrconf_table[] = {
|
||||
/*
|
||||
* [5:4] row(13+n)
|
||||
* [1:0] col(9+n), assume bw=2
|
||||
* row col,bw
|
||||
*/
|
||||
0,
|
||||
((2 << DDRCONF_ROW_SHIFT) | 1 << DDRCONF_COL_SHIFT),
|
||||
((1 << DDRCONF_ROW_SHIFT) | 1 << DDRCONF_COL_SHIFT),
|
||||
((0 << DDRCONF_ROW_SHIFT) | 1 << DDRCONF_COL_SHIFT),
|
||||
((2 << DDRCONF_ROW_SHIFT) | 2 << DDRCONF_COL_SHIFT),
|
||||
((1 << DDRCONF_ROW_SHIFT) | 2 << DDRCONF_COL_SHIFT),
|
||||
((0 << DDRCONF_ROW_SHIFT) | 2 << DDRCONF_COL_SHIFT),
|
||||
((1 << DDRCONF_ROW_SHIFT) | 0 << DDRCONF_COL_SHIFT),
|
||||
((0 << DDRCONF_ROW_SHIFT) | 0 << DDRCONF_COL_SHIFT),
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
};
|
||||
|
||||
#define TEST_PATTEN 0x5aa5f00f
|
||||
#define DQS_GATE_TRAINING_ERROR_RANK0 (1 << 4)
|
||||
#define DQS_GATE_TRAINING_ERROR_RANK1 (2 << 4)
|
||||
|
||||
#ifdef CONFIG_SPL_BUILD
|
||||
static void copy_to_reg(u32 *dest, const u32 *src, u32 n)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < n / sizeof(u32); i++) {
|
||||
writel(*src, dest);
|
||||
src++;
|
||||
dest++;
|
||||
}
|
||||
}
|
||||
|
||||
static void ddr_reset(struct rk3188_cru *cru, u32 ch, u32 ctl, u32 phy)
|
||||
{
|
||||
u32 phy_ctl_srstn_shift = 13;
|
||||
u32 ctl_psrstn_shift = 11;
|
||||
u32 ctl_srstn_shift = 10;
|
||||
u32 phy_psrstn_shift = 9;
|
||||
u32 phy_srstn_shift = 8;
|
||||
|
||||
rk_clrsetreg(&cru->cru_softrst_con[5],
|
||||
1 << phy_ctl_srstn_shift | 1 << ctl_psrstn_shift |
|
||||
1 << ctl_srstn_shift | 1 << phy_psrstn_shift |
|
||||
1 << phy_srstn_shift,
|
||||
phy << phy_ctl_srstn_shift | ctl << ctl_psrstn_shift |
|
||||
ctl << ctl_srstn_shift | phy << phy_psrstn_shift |
|
||||
phy << phy_srstn_shift);
|
||||
}
|
||||
|
||||
static void ddr_phy_ctl_reset(struct rk3188_cru *cru, u32 ch, u32 n)
|
||||
{
|
||||
u32 phy_ctl_srstn_shift = 13;
|
||||
|
||||
rk_clrsetreg(&cru->cru_softrst_con[5],
|
||||
1 << phy_ctl_srstn_shift, n << phy_ctl_srstn_shift);
|
||||
}
|
||||
|
||||
static void phy_pctrl_reset(struct rk3188_cru *cru,
|
||||
struct rk3288_ddr_publ *publ,
|
||||
int channel)
|
||||
{
|
||||
int i;
|
||||
|
||||
ddr_reset(cru, channel, 1, 1);
|
||||
udelay(1);
|
||||
clrbits_le32(&publ->acdllcr, ACDLLCR_DLLSRST);
|
||||
for (i = 0; i < 4; i++)
|
||||
clrbits_le32(&publ->datx8[i].dxdllcr, DXDLLCR_DLLSRST);
|
||||
|
||||
udelay(10);
|
||||
setbits_le32(&publ->acdllcr, ACDLLCR_DLLSRST);
|
||||
for (i = 0; i < 4; i++)
|
||||
setbits_le32(&publ->datx8[i].dxdllcr, DXDLLCR_DLLSRST);
|
||||
|
||||
udelay(10);
|
||||
ddr_reset(cru, channel, 1, 0);
|
||||
udelay(10);
|
||||
ddr_reset(cru, channel, 0, 0);
|
||||
udelay(10);
|
||||
}
|
||||
|
||||
static void phy_dll_bypass_set(struct rk3288_ddr_publ *publ,
|
||||
u32 freq)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (freq <= 250000000) {
|
||||
if (freq <= 150000000)
|
||||
clrbits_le32(&publ->dllgcr, SBIAS_BYPASS);
|
||||
else
|
||||
setbits_le32(&publ->dllgcr, SBIAS_BYPASS);
|
||||
setbits_le32(&publ->acdllcr, ACDLLCR_DLLDIS);
|
||||
for (i = 0; i < 4; i++)
|
||||
setbits_le32(&publ->datx8[i].dxdllcr,
|
||||
DXDLLCR_DLLDIS);
|
||||
|
||||
setbits_le32(&publ->pir, PIR_DLLBYP);
|
||||
} else {
|
||||
clrbits_le32(&publ->dllgcr, SBIAS_BYPASS);
|
||||
clrbits_le32(&publ->acdllcr, ACDLLCR_DLLDIS);
|
||||
for (i = 0; i < 4; i++) {
|
||||
clrbits_le32(&publ->datx8[i].dxdllcr,
|
||||
DXDLLCR_DLLDIS);
|
||||
}
|
||||
|
||||
clrbits_le32(&publ->pir, PIR_DLLBYP);
|
||||
}
|
||||
}
|
||||
|
||||
static void dfi_cfg(struct rk3288_ddr_pctl *pctl, u32 dramtype)
|
||||
{
|
||||
writel(DFI_INIT_START, &pctl->dfistcfg0);
|
||||
writel(DFI_DRAM_CLK_SR_EN | DFI_DRAM_CLK_DPD_EN,
|
||||
&pctl->dfistcfg1);
|
||||
writel(DFI_PARITY_INTR_EN | DFI_PARITY_EN, &pctl->dfistcfg2);
|
||||
writel(7 << TLP_RESP_TIME_SHIFT | LP_SR_EN | LP_PD_EN,
|
||||
&pctl->dfilpcfg0);
|
||||
|
||||
writel(2 << TCTRL_DELAY_TIME_SHIFT, &pctl->dfitctrldelay);
|
||||
writel(1 << TPHY_WRDATA_TIME_SHIFT, &pctl->dfitphywrdata);
|
||||
writel(0xf << TPHY_RDLAT_TIME_SHIFT, &pctl->dfitphyrdlat);
|
||||
writel(2 << TDRAM_CLK_DIS_TIME_SHIFT, &pctl->dfitdramclkdis);
|
||||
writel(2 << TDRAM_CLK_EN_TIME_SHIFT, &pctl->dfitdramclken);
|
||||
writel(1, &pctl->dfitphyupdtype0);
|
||||
|
||||
/* cs0 and cs1 write odt enable */
|
||||
writel((RANK0_ODT_WRITE_SEL | RANK1_ODT_WRITE_SEL),
|
||||
&pctl->dfiodtcfg);
|
||||
/* odt write length */
|
||||
writel(7 << ODT_LEN_BL8_W_SHIFT, &pctl->dfiodtcfg1);
|
||||
/* phyupd and ctrlupd disabled */
|
||||
writel(0, &pctl->dfiupdcfg);
|
||||
}
|
||||
|
||||
static void ddr_set_enable(struct rk3188_grf *grf, uint channel, bool enable)
|
||||
{
|
||||
uint val = 0;
|
||||
|
||||
if (enable)
|
||||
val = 1 << DDR_16BIT_EN_SHIFT;
|
||||
|
||||
rk_clrsetreg(&grf->ddrc_con0, 1 << DDR_16BIT_EN_SHIFT, val);
|
||||
}
|
||||
|
||||
static void ddr_set_ddr3_mode(struct rk3188_grf *grf, uint channel,
|
||||
bool ddr3_mode)
|
||||
{
|
||||
uint mask, val;
|
||||
|
||||
mask = MSCH4_MAINDDR3_MASK << MSCH4_MAINDDR3_SHIFT;
|
||||
val = ddr3_mode << MSCH4_MAINDDR3_SHIFT;
|
||||
rk_clrsetreg(&grf->soc_con2, mask, val);
|
||||
}
|
||||
|
||||
static void ddr_rank_2_row15en(struct rk3188_grf *grf, bool enable)
|
||||
{
|
||||
uint mask, val;
|
||||
|
||||
mask = RANK_TO_ROW15_EN_MASK << RANK_TO_ROW15_EN_SHIFT;
|
||||
val = enable << RANK_TO_ROW15_EN_SHIFT;
|
||||
rk_clrsetreg(&grf->soc_con2, mask, val);
|
||||
}
|
||||
|
||||
static void pctl_cfg(int channel, struct rk3288_ddr_pctl *pctl,
|
||||
struct rk3188_sdram_params *sdram_params,
|
||||
struct rk3188_grf *grf)
|
||||
{
|
||||
copy_to_reg(&pctl->togcnt1u, &sdram_params->pctl_timing.togcnt1u,
|
||||
sizeof(sdram_params->pctl_timing));
|
||||
switch (sdram_params->base.dramtype) {
|
||||
case DDR3:
|
||||
if (sdram_params->phy_timing.mr[1] & DDR3_DLL_DISABLE) {
|
||||
writel(sdram_params->pctl_timing.tcl - 3,
|
||||
&pctl->dfitrddataen);
|
||||
} else {
|
||||
writel(sdram_params->pctl_timing.tcl - 2,
|
||||
&pctl->dfitrddataen);
|
||||
}
|
||||
writel(sdram_params->pctl_timing.tcwl - 1,
|
||||
&pctl->dfitphywrlat);
|
||||
writel(0 << MDDR_LPDDR2_CLK_STOP_IDLE_SHIFT | DDR3_EN |
|
||||
DDR2_DDR3_BL_8 | (6 - 4) << TFAW_SHIFT | PD_EXIT_SLOW |
|
||||
1 << PD_TYPE_SHIFT | 0 << PD_IDLE_SHIFT,
|
||||
&pctl->mcfg);
|
||||
ddr_set_ddr3_mode(grf, channel, true);
|
||||
ddr_set_enable(grf, channel, true);
|
||||
break;
|
||||
}
|
||||
|
||||
setbits_le32(&pctl->scfg, 1);
|
||||
}
|
||||
|
||||
static void phy_cfg(const struct chan_info *chan, int channel,
|
||||
struct rk3188_sdram_params *sdram_params)
|
||||
{
|
||||
struct rk3288_ddr_publ *publ = chan->publ;
|
||||
struct rk3188_msch *msch = chan->msch;
|
||||
uint ddr_freq_mhz = sdram_params->base.ddr_freq / 1000000;
|
||||
u32 dinit2;
|
||||
int i;
|
||||
|
||||
dinit2 = DIV_ROUND_UP(ddr_freq_mhz * 200000, 1000);
|
||||
/* DDR PHY Timing */
|
||||
copy_to_reg(&publ->dtpr[0], &sdram_params->phy_timing.dtpr0,
|
||||
sizeof(sdram_params->phy_timing));
|
||||
writel(sdram_params->base.noc_timing, &msch->ddrtiming);
|
||||
writel(0x3f, &msch->readlatency);
|
||||
writel(DIV_ROUND_UP(ddr_freq_mhz * 5120, 1000) << PRT_DLLLOCK_SHIFT |
|
||||
DIV_ROUND_UP(ddr_freq_mhz * 50, 1000) << PRT_DLLSRST_SHIFT |
|
||||
8 << PRT_ITMSRST_SHIFT, &publ->ptr[0]);
|
||||
writel(DIV_ROUND_UP(ddr_freq_mhz * 500000, 1000) << PRT_DINIT0_SHIFT |
|
||||
DIV_ROUND_UP(ddr_freq_mhz * 400, 1000) << PRT_DINIT1_SHIFT,
|
||||
&publ->ptr[1]);
|
||||
writel(min(dinit2, 0x1ffffU) << PRT_DINIT2_SHIFT |
|
||||
DIV_ROUND_UP(ddr_freq_mhz * 1000, 1000) << PRT_DINIT3_SHIFT,
|
||||
&publ->ptr[2]);
|
||||
|
||||
switch (sdram_params->base.dramtype) {
|
||||
case DDR3:
|
||||
clrbits_le32(&publ->pgcr, 0x1f);
|
||||
clrsetbits_le32(&publ->dcr, DDRMD_MASK << DDRMD_SHIFT,
|
||||
DDRMD_DDR3 << DDRMD_SHIFT);
|
||||
break;
|
||||
}
|
||||
if (sdram_params->base.odt) {
|
||||
/*dynamic RTT enable */
|
||||
for (i = 0; i < 4; i++)
|
||||
setbits_le32(&publ->datx8[i].dxgcr, DQSRTT | DQRTT);
|
||||
} else {
|
||||
/*dynamic RTT disable */
|
||||
for (i = 0; i < 4; i++)
|
||||
clrbits_le32(&publ->datx8[i].dxgcr, DQSRTT | DQRTT);
|
||||
}
|
||||
}
|
||||
|
||||
static void phy_init(struct rk3288_ddr_publ *publ)
|
||||
{
|
||||
setbits_le32(&publ->pir, PIR_INIT | PIR_DLLSRST
|
||||
| PIR_DLLLOCK | PIR_ZCAL | PIR_ITMSRST | PIR_CLRSR);
|
||||
udelay(1);
|
||||
while ((readl(&publ->pgsr) &
|
||||
(PGSR_IDONE | PGSR_DLDONE | PGSR_ZCDONE)) !=
|
||||
(PGSR_IDONE | PGSR_DLDONE | PGSR_ZCDONE))
|
||||
;
|
||||
}
|
||||
|
||||
static void send_command(struct rk3288_ddr_pctl *pctl, u32 rank,
|
||||
u32 cmd, u32 arg)
|
||||
{
|
||||
writel((START_CMD | (rank << 20) | arg | cmd), &pctl->mcmd);
|
||||
udelay(1);
|
||||
while (readl(&pctl->mcmd) & START_CMD)
|
||||
;
|
||||
}
|
||||
|
||||
static inline void send_command_op(struct rk3288_ddr_pctl *pctl,
|
||||
u32 rank, u32 cmd, u32 ma, u32 op)
|
||||
{
|
||||
send_command(pctl, rank, cmd, (ma & LPDDR2_MA_MASK) << LPDDR2_MA_SHIFT |
|
||||
(op & LPDDR2_OP_MASK) << LPDDR2_OP_SHIFT);
|
||||
}
|
||||
|
||||
static void memory_init(struct rk3288_ddr_publ *publ,
|
||||
u32 dramtype)
|
||||
{
|
||||
setbits_le32(&publ->pir,
|
||||
(PIR_INIT | PIR_DRAMINIT | PIR_LOCKBYP
|
||||
| PIR_ZCALBYP | PIR_CLRSR | PIR_ICPC
|
||||
| (dramtype == DDR3 ? PIR_DRAMRST : 0)));
|
||||
udelay(1);
|
||||
while ((readl(&publ->pgsr) & (PGSR_IDONE | PGSR_DLDONE))
|
||||
!= (PGSR_IDONE | PGSR_DLDONE))
|
||||
;
|
||||
}
|
||||
|
||||
static void move_to_config_state(struct rk3288_ddr_publ *publ,
|
||||
struct rk3288_ddr_pctl *pctl)
|
||||
{
|
||||
unsigned int state;
|
||||
|
||||
while (1) {
|
||||
state = readl(&pctl->stat) & PCTL_STAT_MSK;
|
||||
|
||||
switch (state) {
|
||||
case LOW_POWER:
|
||||
writel(WAKEUP_STATE, &pctl->sctl);
|
||||
while ((readl(&pctl->stat) & PCTL_STAT_MSK)
|
||||
!= ACCESS)
|
||||
;
|
||||
/* wait DLL lock */
|
||||
while ((readl(&publ->pgsr) & PGSR_DLDONE)
|
||||
!= PGSR_DLDONE)
|
||||
;
|
||||
/*
|
||||
* if at low power state,need wakeup first,
|
||||
* and then enter the config, so
|
||||
* fallthrough
|
||||
*/
|
||||
case ACCESS:
|
||||
/* fallthrough */
|
||||
case INIT_MEM:
|
||||
writel(CFG_STATE, &pctl->sctl);
|
||||
while ((readl(&pctl->stat) & PCTL_STAT_MSK) != CONFIG)
|
||||
;
|
||||
break;
|
||||
case CONFIG:
|
||||
return;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void set_bandwidth_ratio(const struct chan_info *chan, int channel,
|
||||
u32 n, struct rk3188_grf *grf)
|
||||
{
|
||||
struct rk3288_ddr_pctl *pctl = chan->pctl;
|
||||
struct rk3288_ddr_publ *publ = chan->publ;
|
||||
struct rk3188_msch *msch = chan->msch;
|
||||
|
||||
if (n == 1) {
|
||||
setbits_le32(&pctl->ppcfg, 1);
|
||||
ddr_set_enable(grf, channel, 1);
|
||||
setbits_le32(&msch->ddrtiming, 1 << 31);
|
||||
/* Data Byte disable*/
|
||||
clrbits_le32(&publ->datx8[2].dxgcr, 1);
|
||||
clrbits_le32(&publ->datx8[3].dxgcr, 1);
|
||||
/* disable DLL */
|
||||
setbits_le32(&publ->datx8[2].dxdllcr, DXDLLCR_DLLDIS);
|
||||
setbits_le32(&publ->datx8[3].dxdllcr, DXDLLCR_DLLDIS);
|
||||
} else {
|
||||
clrbits_le32(&pctl->ppcfg, 1);
|
||||
ddr_set_enable(grf, channel, 0);
|
||||
clrbits_le32(&msch->ddrtiming, 1 << 31);
|
||||
/* Data Byte enable*/
|
||||
setbits_le32(&publ->datx8[2].dxgcr, 1);
|
||||
setbits_le32(&publ->datx8[3].dxgcr, 1);
|
||||
|
||||
/* enable DLL */
|
||||
clrbits_le32(&publ->datx8[2].dxdllcr, DXDLLCR_DLLDIS);
|
||||
clrbits_le32(&publ->datx8[3].dxdllcr, DXDLLCR_DLLDIS);
|
||||
/* reset DLL */
|
||||
clrbits_le32(&publ->datx8[2].dxdllcr, DXDLLCR_DLLSRST);
|
||||
clrbits_le32(&publ->datx8[3].dxdllcr, DXDLLCR_DLLSRST);
|
||||
udelay(10);
|
||||
setbits_le32(&publ->datx8[2].dxdllcr, DXDLLCR_DLLSRST);
|
||||
setbits_le32(&publ->datx8[3].dxdllcr, DXDLLCR_DLLSRST);
|
||||
}
|
||||
setbits_le32(&pctl->dfistcfg0, 1 << 2);
|
||||
}
|
||||
|
||||
static int data_training(const struct chan_info *chan, int channel,
|
||||
struct rk3188_sdram_params *sdram_params)
|
||||
{
|
||||
unsigned int j;
|
||||
int ret = 0;
|
||||
u32 rank;
|
||||
int i;
|
||||
u32 step[2] = { PIR_QSTRN, PIR_RVTRN };
|
||||
struct rk3288_ddr_publ *publ = chan->publ;
|
||||
struct rk3288_ddr_pctl *pctl = chan->pctl;
|
||||
|
||||
/* disable auto refresh */
|
||||
writel(0, &pctl->trefi);
|
||||
|
||||
if (sdram_params->base.dramtype != LPDDR3)
|
||||
setbits_le32(&publ->pgcr, 1 << PGCR_DQSCFG_SHIFT);
|
||||
rank = sdram_params->ch[channel].rank | 1;
|
||||
for (j = 0; j < ARRAY_SIZE(step); j++) {
|
||||
/*
|
||||
* trigger QSTRN and RVTRN
|
||||
* clear DTDONE status
|
||||
*/
|
||||
setbits_le32(&publ->pir, PIR_CLRSR);
|
||||
|
||||
/* trigger DTT */
|
||||
setbits_le32(&publ->pir,
|
||||
PIR_INIT | step[j] | PIR_LOCKBYP | PIR_ZCALBYP |
|
||||
PIR_CLRSR);
|
||||
udelay(1);
|
||||
/* wait echo byte DTDONE */
|
||||
while ((readl(&publ->datx8[0].dxgsr[0]) & rank)
|
||||
!= rank)
|
||||
;
|
||||
while ((readl(&publ->datx8[1].dxgsr[0]) & rank)
|
||||
!= rank)
|
||||
;
|
||||
if (!(readl(&pctl->ppcfg) & 1)) {
|
||||
while ((readl(&publ->datx8[2].dxgsr[0])
|
||||
& rank) != rank)
|
||||
;
|
||||
while ((readl(&publ->datx8[3].dxgsr[0])
|
||||
& rank) != rank)
|
||||
;
|
||||
}
|
||||
if (readl(&publ->pgsr) &
|
||||
(PGSR_DTERR | PGSR_RVERR | PGSR_RVEIRR)) {
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* send some auto refresh to complement the lost while DTT */
|
||||
for (i = 0; i < (rank > 1 ? 8 : 4); i++)
|
||||
send_command(pctl, rank, REF_CMD, 0);
|
||||
|
||||
if (sdram_params->base.dramtype != LPDDR3)
|
||||
clrbits_le32(&publ->pgcr, 1 << PGCR_DQSCFG_SHIFT);
|
||||
|
||||
/* resume auto refresh */
|
||||
writel(sdram_params->pctl_timing.trefi, &pctl->trefi);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void move_to_access_state(const struct chan_info *chan)
|
||||
{
|
||||
struct rk3288_ddr_publ *publ = chan->publ;
|
||||
struct rk3288_ddr_pctl *pctl = chan->pctl;
|
||||
unsigned int state;
|
||||
|
||||
while (1) {
|
||||
state = readl(&pctl->stat) & PCTL_STAT_MSK;
|
||||
|
||||
switch (state) {
|
||||
case LOW_POWER:
|
||||
if (((readl(&pctl->stat) >> LP_TRIG_SHIFT) &
|
||||
LP_TRIG_MASK) == 1)
|
||||
return;
|
||||
|
||||
writel(WAKEUP_STATE, &pctl->sctl);
|
||||
while ((readl(&pctl->stat) & PCTL_STAT_MSK) != ACCESS)
|
||||
;
|
||||
/* wait DLL lock */
|
||||
while ((readl(&publ->pgsr) & PGSR_DLDONE)
|
||||
!= PGSR_DLDONE)
|
||||
;
|
||||
break;
|
||||
case INIT_MEM:
|
||||
writel(CFG_STATE, &pctl->sctl);
|
||||
while ((readl(&pctl->stat) & PCTL_STAT_MSK) != CONFIG)
|
||||
;
|
||||
/* fallthrough */
|
||||
case CONFIG:
|
||||
writel(GO_STATE, &pctl->sctl);
|
||||
while ((readl(&pctl->stat) & PCTL_STAT_MSK) == CONFIG)
|
||||
;
|
||||
break;
|
||||
case ACCESS:
|
||||
return;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void dram_cfg_rbc(const struct chan_info *chan, u32 chnum,
|
||||
struct rk3188_sdram_params *sdram_params)
|
||||
{
|
||||
struct rk3288_ddr_publ *publ = chan->publ;
|
||||
|
||||
if (sdram_params->ch[chnum].bk == 3)
|
||||
clrsetbits_le32(&publ->dcr, PDQ_MASK << PDQ_SHIFT,
|
||||
1 << PDQ_SHIFT);
|
||||
else
|
||||
clrbits_le32(&publ->dcr, PDQ_MASK << PDQ_SHIFT);
|
||||
|
||||
writel(sdram_params->base.ddrconfig, &chan->msch->ddrconf);
|
||||
}
|
||||
|
||||
static void dram_all_config(const struct dram_info *dram,
|
||||
struct rk3188_sdram_params *sdram_params)
|
||||
{
|
||||
unsigned int chan;
|
||||
u32 sys_reg = 0;
|
||||
|
||||
sys_reg |= sdram_params->base.dramtype << SYS_REG_DDRTYPE_SHIFT;
|
||||
sys_reg |= (sdram_params->num_channels - 1) << SYS_REG_NUM_CH_SHIFT;
|
||||
for (chan = 0; chan < sdram_params->num_channels; chan++) {
|
||||
const struct rk3288_sdram_channel *info =
|
||||
&sdram_params->ch[chan];
|
||||
|
||||
sys_reg |= info->row_3_4 << SYS_REG_ROW_3_4_SHIFT(chan);
|
||||
sys_reg |= 1 << SYS_REG_CHINFO_SHIFT(chan);
|
||||
sys_reg |= (info->rank - 1) << SYS_REG_RANK_SHIFT(chan);
|
||||
sys_reg |= (info->col - 9) << SYS_REG_COL_SHIFT(chan);
|
||||
sys_reg |= info->bk == 3 ? 0 : 1 << SYS_REG_BK_SHIFT(chan);
|
||||
sys_reg |= (info->cs0_row - 13) << SYS_REG_CS0_ROW_SHIFT(chan);
|
||||
sys_reg |= (info->cs1_row - 13) << SYS_REG_CS1_ROW_SHIFT(chan);
|
||||
sys_reg |= (2 >> info->bw) << SYS_REG_BW_SHIFT(chan);
|
||||
sys_reg |= (2 >> info->dbw) << SYS_REG_DBW_SHIFT(chan);
|
||||
|
||||
dram_cfg_rbc(&dram->chan[chan], chan, sdram_params);
|
||||
}
|
||||
if (sdram_params->ch[0].rank == 2)
|
||||
ddr_rank_2_row15en(dram->grf, 0);
|
||||
else
|
||||
ddr_rank_2_row15en(dram->grf, 1);
|
||||
|
||||
writel(sys_reg, &dram->pmu->sys_reg[2]);
|
||||
}
|
||||
|
||||
static int sdram_rank_bw_detect(struct dram_info *dram, int channel,
|
||||
struct rk3188_sdram_params *sdram_params)
|
||||
{
|
||||
int reg;
|
||||
int need_trainig = 0;
|
||||
const struct chan_info *chan = &dram->chan[channel];
|
||||
struct rk3288_ddr_publ *publ = chan->publ;
|
||||
|
||||
ddr_rank_2_row15en(dram->grf, 0);
|
||||
|
||||
if (data_training(chan, channel, sdram_params) < 0) {
|
||||
printf("first data training fail!\n");
|
||||
reg = readl(&publ->datx8[0].dxgsr[0]);
|
||||
/* Check the result for rank 0 */
|
||||
if ((channel == 0) && (reg & DQS_GATE_TRAINING_ERROR_RANK0)) {
|
||||
printf("data training fail!\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
/* Check the result for rank 1 */
|
||||
if (reg & DQS_GATE_TRAINING_ERROR_RANK1) {
|
||||
sdram_params->ch[channel].rank = 1;
|
||||
clrsetbits_le32(&publ->pgcr, 0xF << 18,
|
||||
sdram_params->ch[channel].rank << 18);
|
||||
need_trainig = 1;
|
||||
}
|
||||
reg = readl(&publ->datx8[2].dxgsr[0]);
|
||||
if (reg & (1 << 4)) {
|
||||
sdram_params->ch[channel].bw = 1;
|
||||
set_bandwidth_ratio(chan, channel,
|
||||
sdram_params->ch[channel].bw,
|
||||
dram->grf);
|
||||
need_trainig = 1;
|
||||
}
|
||||
}
|
||||
/* Assume the Die bit width are the same with the chip bit width */
|
||||
sdram_params->ch[channel].dbw = sdram_params->ch[channel].bw;
|
||||
|
||||
if (need_trainig &&
|
||||
(data_training(chan, channel, sdram_params) < 0)) {
|
||||
if (sdram_params->base.dramtype == LPDDR3) {
|
||||
ddr_phy_ctl_reset(dram->cru, channel, 1);
|
||||
udelay(10);
|
||||
ddr_phy_ctl_reset(dram->cru, channel, 0);
|
||||
udelay(10);
|
||||
}
|
||||
printf("2nd data training failed!");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Detect ram columns and rows.
|
||||
* @dram: dram info struct
|
||||
* @channel: channel number to handle
|
||||
* @sdram_params: sdram parameters, function will fill in col and row values
|
||||
*
|
||||
* Returns 0 or negative on error.
|
||||
*/
|
||||
static int sdram_col_row_detect(struct dram_info *dram, int channel,
|
||||
struct rk3188_sdram_params *sdram_params)
|
||||
{
|
||||
int row, col;
|
||||
unsigned int addr;
|
||||
const struct chan_info *chan = &dram->chan[channel];
|
||||
struct rk3288_ddr_pctl *pctl = chan->pctl;
|
||||
struct rk3288_ddr_publ *publ = chan->publ;
|
||||
int ret = 0;
|
||||
|
||||
/* Detect col */
|
||||
for (col = 11; col >= 9; col--) {
|
||||
writel(0, CONFIG_SYS_SDRAM_BASE);
|
||||
addr = CONFIG_SYS_SDRAM_BASE +
|
||||
(1 << (col + sdram_params->ch[channel].bw - 1));
|
||||
writel(TEST_PATTEN, addr);
|
||||
if ((readl(addr) == TEST_PATTEN) &&
|
||||
(readl(CONFIG_SYS_SDRAM_BASE) == 0))
|
||||
break;
|
||||
}
|
||||
if (col == 8) {
|
||||
printf("Col detect error\n");
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
} else {
|
||||
sdram_params->ch[channel].col = col;
|
||||
}
|
||||
|
||||
ddr_rank_2_row15en(dram->grf, 1);
|
||||
move_to_config_state(publ, pctl);
|
||||
writel(1, &chan->msch->ddrconf);
|
||||
move_to_access_state(chan);
|
||||
/* Detect row, max 15,min13 in rk3188*/
|
||||
for (row = 16; row >= 13; row--) {
|
||||
writel(0, CONFIG_SYS_SDRAM_BASE);
|
||||
addr = CONFIG_SYS_SDRAM_BASE + (1 << (row + 15 - 1));
|
||||
writel(TEST_PATTEN, addr);
|
||||
if ((readl(addr) == TEST_PATTEN) &&
|
||||
(readl(CONFIG_SYS_SDRAM_BASE) == 0))
|
||||
break;
|
||||
}
|
||||
if (row == 12) {
|
||||
printf("Row detect error\n");
|
||||
ret = -EINVAL;
|
||||
} else {
|
||||
sdram_params->ch[channel].cs1_row = row;
|
||||
sdram_params->ch[channel].row_3_4 = 0;
|
||||
debug("chn %d col %d, row %d\n", channel, col, row);
|
||||
sdram_params->ch[channel].cs0_row = row;
|
||||
}
|
||||
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int sdram_get_niu_config(struct rk3188_sdram_params *sdram_params)
|
||||
{
|
||||
int i, tmp, size, row, ret = 0;
|
||||
|
||||
row = sdram_params->ch[0].cs0_row;
|
||||
/*
|
||||
* RK3188 share the rank and row bit15, we use same ddr config for 15bit
|
||||
* and 16bit row
|
||||
*/
|
||||
if (row == 16)
|
||||
row = 15;
|
||||
tmp = sdram_params->ch[0].col - 9;
|
||||
tmp -= (sdram_params->ch[0].bw == 2) ? 0 : 1;
|
||||
tmp |= ((row - 13) << 4);
|
||||
size = sizeof(ddrconf_table)/sizeof(ddrconf_table[0]);
|
||||
for (i = 0; i < size; i++)
|
||||
if (tmp == ddrconf_table[i])
|
||||
break;
|
||||
if (i >= size) {
|
||||
printf("niu config not found\n");
|
||||
ret = -EINVAL;
|
||||
} else {
|
||||
debug("niu config %d\n", i);
|
||||
sdram_params->base.ddrconfig = i;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int sdram_init(struct dram_info *dram,
|
||||
struct rk3188_sdram_params *sdram_params)
|
||||
{
|
||||
int channel;
|
||||
int zqcr;
|
||||
int ret;
|
||||
|
||||
if ((sdram_params->base.dramtype == DDR3 &&
|
||||
sdram_params->base.ddr_freq > 800000000)) {
|
||||
printf("SDRAM frequency is too high!");
|
||||
return -E2BIG;
|
||||
}
|
||||
|
||||
ret = clk_set_rate(&dram->ddr_clk, sdram_params->base.ddr_freq);
|
||||
if (ret) {
|
||||
printf("Could not set DDR clock\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
for (channel = 0; channel < 1; channel++) {
|
||||
const struct chan_info *chan = &dram->chan[channel];
|
||||
struct rk3288_ddr_pctl *pctl = chan->pctl;
|
||||
struct rk3288_ddr_publ *publ = chan->publ;
|
||||
|
||||
phy_pctrl_reset(dram->cru, publ, channel);
|
||||
phy_dll_bypass_set(publ, sdram_params->base.ddr_freq);
|
||||
|
||||
dfi_cfg(pctl, sdram_params->base.dramtype);
|
||||
|
||||
pctl_cfg(channel, pctl, sdram_params, dram->grf);
|
||||
|
||||
phy_cfg(chan, channel, sdram_params);
|
||||
|
||||
phy_init(publ);
|
||||
|
||||
writel(POWER_UP_START, &pctl->powctl);
|
||||
while (!(readl(&pctl->powstat) & POWER_UP_DONE))
|
||||
;
|
||||
|
||||
memory_init(publ, sdram_params->base.dramtype);
|
||||
move_to_config_state(publ, pctl);
|
||||
|
||||
/* Using 32bit bus width for detect */
|
||||
sdram_params->ch[channel].bw = 2;
|
||||
set_bandwidth_ratio(chan, channel,
|
||||
sdram_params->ch[channel].bw, dram->grf);
|
||||
/*
|
||||
* set cs, using n=3 for detect
|
||||
* CS0, n=1
|
||||
* CS1, n=2
|
||||
* CS0 & CS1, n = 3
|
||||
*/
|
||||
sdram_params->ch[channel].rank = 2,
|
||||
clrsetbits_le32(&publ->pgcr, 0xF << 18,
|
||||
(sdram_params->ch[channel].rank | 1) << 18);
|
||||
|
||||
/* DS=40ohm,ODT=155ohm */
|
||||
zqcr = 1 << ZDEN_SHIFT | 2 << PU_ONDIE_SHIFT |
|
||||
2 << PD_ONDIE_SHIFT | 0x19 << PU_OUTPUT_SHIFT |
|
||||
0x19 << PD_OUTPUT_SHIFT;
|
||||
writel(zqcr, &publ->zq1cr[0]);
|
||||
writel(zqcr, &publ->zq0cr[0]);
|
||||
|
||||
/* Detect the rank and bit-width with data-training */
|
||||
writel(1, &chan->msch->ddrconf);
|
||||
sdram_rank_bw_detect(dram, channel, sdram_params);
|
||||
|
||||
if (sdram_params->base.dramtype == LPDDR3) {
|
||||
u32 i;
|
||||
writel(0, &pctl->mrrcfg0);
|
||||
for (i = 0; i < 17; i++)
|
||||
send_command_op(pctl, 1, MRR_CMD, i, 0);
|
||||
}
|
||||
writel(4, &chan->msch->ddrconf);
|
||||
move_to_access_state(chan);
|
||||
/* DDR3 and LPDDR3 are always 8 bank, no need detect */
|
||||
sdram_params->ch[channel].bk = 3;
|
||||
/* Detect Col and Row number*/
|
||||
ret = sdram_col_row_detect(dram, channel, sdram_params);
|
||||
if (ret)
|
||||
goto error;
|
||||
}
|
||||
/* Find NIU DDR configuration */
|
||||
ret = sdram_get_niu_config(sdram_params);
|
||||
if (ret)
|
||||
goto error;
|
||||
|
||||
dram_all_config(dram, sdram_params);
|
||||
debug("%s done\n", __func__);
|
||||
|
||||
return 0;
|
||||
error:
|
||||
printf("DRAM init failed!\n");
|
||||
hang();
|
||||
}
|
||||
|
||||
static int setup_sdram(struct udevice *dev)
|
||||
{
|
||||
struct dram_info *priv = dev_get_priv(dev);
|
||||
struct rk3188_sdram_params *params = dev_get_platdata(dev);
|
||||
|
||||
return sdram_init(priv, params);
|
||||
}
|
||||
|
||||
static int rk3188_dmc_ofdata_to_platdata(struct udevice *dev)
|
||||
{
|
||||
#if !CONFIG_IS_ENABLED(OF_PLATDATA)
|
||||
struct rk3188_sdram_params *params = dev_get_platdata(dev);
|
||||
int ret;
|
||||
|
||||
/* rk3188 supports only one-channel */
|
||||
params->num_channels = 1;
|
||||
ret = dev_read_u32_array(dev, "rockchip,pctl-timing",
|
||||
(u32 *)¶ms->pctl_timing,
|
||||
sizeof(params->pctl_timing) / sizeof(u32));
|
||||
if (ret) {
|
||||
printf("%s: Cannot read rockchip,pctl-timing\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
ret = dev_read_u32_array(dev, "rockchip,phy-timing",
|
||||
(u32 *)¶ms->phy_timing,
|
||||
sizeof(params->phy_timing) / sizeof(u32));
|
||||
if (ret) {
|
||||
printf("%s: Cannot read rockchip,phy-timing\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
ret = dev_read_u32_array(dev, "rockchip,sdram-params",
|
||||
(u32 *)¶ms->base,
|
||||
sizeof(params->base) / sizeof(u32));
|
||||
if (ret) {
|
||||
printf("%s: Cannot read rockchip,sdram-params\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
ret = regmap_init_mem(dev_ofnode(dev), ¶ms->map);
|
||||
if (ret)
|
||||
return ret;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_SPL_BUILD */
|
||||
|
||||
#if CONFIG_IS_ENABLED(OF_PLATDATA)
|
||||
static int conv_of_platdata(struct udevice *dev)
|
||||
{
|
||||
struct rk3188_sdram_params *plat = dev_get_platdata(dev);
|
||||
struct dtd_rockchip_rk3188_dmc *of_plat = &plat->of_plat;
|
||||
int ret;
|
||||
|
||||
memcpy(&plat->pctl_timing, of_plat->rockchip_pctl_timing,
|
||||
sizeof(plat->pctl_timing));
|
||||
memcpy(&plat->phy_timing, of_plat->rockchip_phy_timing,
|
||||
sizeof(plat->phy_timing));
|
||||
memcpy(&plat->base, of_plat->rockchip_sdram_params, sizeof(plat->base));
|
||||
/* rk3188 supports dual-channel, set default channel num to 2 */
|
||||
plat->num_channels = 1;
|
||||
ret = regmap_init_mem_platdata(dev, of_plat->reg,
|
||||
ARRAY_SIZE(of_plat->reg) / 2,
|
||||
&plat->map);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int rk3188_dmc_probe(struct udevice *dev)
|
||||
{
|
||||
#ifdef CONFIG_SPL_BUILD
|
||||
struct rk3188_sdram_params *plat = dev_get_platdata(dev);
|
||||
struct regmap *map;
|
||||
struct udevice *dev_clk;
|
||||
int ret;
|
||||
#endif
|
||||
struct dram_info *priv = dev_get_priv(dev);
|
||||
|
||||
priv->pmu = syscon_get_first_range(ROCKCHIP_SYSCON_PMU);
|
||||
|
||||
#ifdef CONFIG_SPL_BUILD
|
||||
#if CONFIG_IS_ENABLED(OF_PLATDATA)
|
||||
ret = conv_of_platdata(dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
#endif
|
||||
map = syscon_get_regmap_by_driver_data(ROCKCHIP_SYSCON_NOC);
|
||||
if (IS_ERR(map))
|
||||
return PTR_ERR(map);
|
||||
priv->chan[0].msch = regmap_get_range(map, 0);
|
||||
|
||||
priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
|
||||
|
||||
priv->chan[0].pctl = regmap_get_range(plat->map, 0);
|
||||
priv->chan[0].publ = regmap_get_range(plat->map, 1);
|
||||
|
||||
ret = rockchip_get_clk(&dev_clk);
|
||||
if (ret)
|
||||
return ret;
|
||||
priv->ddr_clk.id = CLK_DDR;
|
||||
ret = clk_request(dev_clk, &priv->ddr_clk);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
priv->cru = rockchip_get_cru();
|
||||
if (IS_ERR(priv->cru))
|
||||
return PTR_ERR(priv->cru);
|
||||
ret = setup_sdram(dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
#else
|
||||
priv->info.base = CONFIG_SYS_SDRAM_BASE;
|
||||
priv->info.size = rockchip_sdram_size(
|
||||
(phys_addr_t)&priv->pmu->sys_reg[2]);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rk3188_dmc_get_info(struct udevice *dev, struct ram_info *info)
|
||||
{
|
||||
struct dram_info *priv = dev_get_priv(dev);
|
||||
|
||||
*info = priv->info;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct ram_ops rk3188_dmc_ops = {
|
||||
.get_info = rk3188_dmc_get_info,
|
||||
};
|
||||
|
||||
static const struct udevice_id rk3188_dmc_ids[] = {
|
||||
{ .compatible = "rockchip,rk3188-dmc" },
|
||||
{ }
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(dmc_rk3188) = {
|
||||
.name = "rockchip_rk3188_dmc",
|
||||
.id = UCLASS_RAM,
|
||||
.of_match = rk3188_dmc_ids,
|
||||
.ops = &rk3188_dmc_ops,
|
||||
#ifdef CONFIG_SPL_BUILD
|
||||
.ofdata_to_platdata = rk3188_dmc_ofdata_to_platdata,
|
||||
#endif
|
||||
.probe = rk3188_dmc_probe,
|
||||
.priv_auto_alloc_size = sizeof(struct dram_info),
|
||||
#ifdef CONFIG_SPL_BUILD
|
||||
.platdata_auto_alloc_size = sizeof(struct rk3188_sdram_params),
|
||||
#endif
|
||||
};
|
||||
@@ -0,0 +1,853 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
|
||||
/*
|
||||
* (C) Copyright 2017 Rockchip Electronics Co., Ltd
|
||||
*/
|
||||
#include <common.h>
|
||||
#include <clk.h>
|
||||
#include <dm.h>
|
||||
#include <dt-structs.h>
|
||||
#include <errno.h>
|
||||
#include <ram.h>
|
||||
#include <regmap.h>
|
||||
#include <syscon.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/arch-rockchip/clock.h>
|
||||
#include <asm/arch-rockchip/cru_rk322x.h>
|
||||
#include <asm/arch-rockchip/grf_rk322x.h>
|
||||
#include <asm/arch-rockchip/hardware.h>
|
||||
#include <asm/arch-rockchip/sdram_rk322x.h>
|
||||
#include <asm/arch-rockchip/uart.h>
|
||||
#include <asm/arch-rockchip/sdram.h>
|
||||
#include <asm/types.h>
|
||||
#include <linux/err.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
struct chan_info {
|
||||
struct rk322x_ddr_pctl *pctl;
|
||||
struct rk322x_ddr_phy *phy;
|
||||
struct rk322x_service_sys *msch;
|
||||
};
|
||||
|
||||
struct dram_info {
|
||||
struct chan_info chan[1];
|
||||
struct ram_info info;
|
||||
struct clk ddr_clk;
|
||||
struct rk322x_cru *cru;
|
||||
struct rk322x_grf *grf;
|
||||
};
|
||||
|
||||
struct rk322x_sdram_params {
|
||||
#if CONFIG_IS_ENABLED(OF_PLATDATA)
|
||||
struct dtd_rockchip_rk3228_dmc of_plat;
|
||||
#endif
|
||||
struct rk322x_sdram_channel ch[1];
|
||||
struct rk322x_pctl_timing pctl_timing;
|
||||
struct rk322x_phy_timing phy_timing;
|
||||
struct rk322x_base_params base;
|
||||
int num_channels;
|
||||
struct regmap *map;
|
||||
};
|
||||
|
||||
#ifdef CONFIG_TPL_BUILD
|
||||
/*
|
||||
* [7:6] bank(n:n bit bank)
|
||||
* [5:4] row(13+n)
|
||||
* [3] cs(0:1 cs, 1:2 cs)
|
||||
* [2:1] bank(n:n bit bank)
|
||||
* [0] col(10+n)
|
||||
*/
|
||||
const char ddr_cfg_2_rbc[] = {
|
||||
((0 << 6) | (0 << 4) | (0 << 3) | (1 << 2) | 1),
|
||||
((0 << 6) | (1 << 4) | (0 << 3) | (1 << 2) | 1),
|
||||
((0 << 6) | (2 << 4) | (0 << 3) | (1 << 2) | 1),
|
||||
((0 << 6) | (3 << 4) | (0 << 3) | (1 << 2) | 1),
|
||||
((0 << 6) | (1 << 4) | (0 << 3) | (1 << 2) | 2),
|
||||
((0 << 6) | (2 << 4) | (0 << 3) | (1 << 2) | 2),
|
||||
((0 << 6) | (3 << 4) | (0 << 3) | (1 << 2) | 2),
|
||||
((0 << 6) | (0 << 4) | (0 << 3) | (1 << 2) | 0),
|
||||
((0 << 6) | (1 << 4) | (0 << 3) | (1 << 2) | 0),
|
||||
((0 << 6) | (2 << 4) | (0 << 3) | (1 << 2) | 0),
|
||||
((0 << 6) | (3 << 4) | (0 << 3) | (1 << 2) | 0),
|
||||
((0 << 6) | (2 << 4) | (0 << 3) | (0 << 2) | 1),
|
||||
((1 << 6) | (1 << 4) | (0 << 3) | (0 << 2) | 2),
|
||||
((1 << 6) | (1 << 4) | (0 << 3) | (0 << 2) | 1),
|
||||
((0 << 6) | (3 << 4) | (1 << 3) | (1 << 2) | 1),
|
||||
((0 << 6) | (3 << 4) | (1 << 3) | (1 << 2) | 0),
|
||||
};
|
||||
|
||||
static void copy_to_reg(u32 *dest, const u32 *src, u32 n)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < n / sizeof(u32); i++) {
|
||||
writel(*src, dest);
|
||||
src++;
|
||||
dest++;
|
||||
}
|
||||
}
|
||||
|
||||
void phy_pctrl_reset(struct rk322x_cru *cru,
|
||||
struct rk322x_ddr_phy *ddr_phy)
|
||||
{
|
||||
rk_clrsetreg(&cru->cru_softrst_con[5], 1 << DDRCTRL_PSRST_SHIFT |
|
||||
1 << DDRCTRL_SRST_SHIFT | 1 << DDRPHY_PSRST_SHIFT |
|
||||
1 << DDRPHY_SRST_SHIFT,
|
||||
1 << DDRCTRL_PSRST_SHIFT | 1 << DDRCTRL_SRST_SHIFT |
|
||||
1 << DDRPHY_PSRST_SHIFT | 1 << DDRPHY_SRST_SHIFT);
|
||||
|
||||
udelay(10);
|
||||
|
||||
rk_clrreg(&cru->cru_softrst_con[5], 1 << DDRPHY_PSRST_SHIFT |
|
||||
1 << DDRPHY_SRST_SHIFT);
|
||||
udelay(10);
|
||||
|
||||
rk_clrreg(&cru->cru_softrst_con[5], 1 << DDRCTRL_PSRST_SHIFT |
|
||||
1 << DDRCTRL_SRST_SHIFT);
|
||||
udelay(10);
|
||||
|
||||
clrbits_le32(&ddr_phy->ddrphy_reg[0],
|
||||
SOFT_RESET_MASK << SOFT_RESET_SHIFT);
|
||||
udelay(10);
|
||||
setbits_le32(&ddr_phy->ddrphy_reg[0],
|
||||
SOFT_DERESET_ANALOG);
|
||||
udelay(5);
|
||||
setbits_le32(&ddr_phy->ddrphy_reg[0],
|
||||
SOFT_DERESET_DIGITAL);
|
||||
|
||||
udelay(1);
|
||||
}
|
||||
|
||||
void phy_dll_bypass_set(struct rk322x_ddr_phy *ddr_phy, u32 freq)
|
||||
{
|
||||
u32 tmp;
|
||||
|
||||
setbits_le32(&ddr_phy->ddrphy_reg[0x13], 0x10);
|
||||
setbits_le32(&ddr_phy->ddrphy_reg[0x26], 0x10);
|
||||
setbits_le32(&ddr_phy->ddrphy_reg[0x36], 0x10);
|
||||
setbits_le32(&ddr_phy->ddrphy_reg[0x46], 0x10);
|
||||
setbits_le32(&ddr_phy->ddrphy_reg[0x56], 0x10);
|
||||
|
||||
clrbits_le32(&ddr_phy->ddrphy_reg[0x14], 0x8);
|
||||
clrbits_le32(&ddr_phy->ddrphy_reg[0x27], 0x8);
|
||||
clrbits_le32(&ddr_phy->ddrphy_reg[0x37], 0x8);
|
||||
clrbits_le32(&ddr_phy->ddrphy_reg[0x47], 0x8);
|
||||
clrbits_le32(&ddr_phy->ddrphy_reg[0x57], 0x8);
|
||||
|
||||
if (freq <= 400)
|
||||
setbits_le32(&ddr_phy->ddrphy_reg[0xa4], 0x1f);
|
||||
else
|
||||
clrbits_le32(&ddr_phy->ddrphy_reg[0xa4], 0x1f);
|
||||
|
||||
if (freq <= 680)
|
||||
tmp = 3;
|
||||
else
|
||||
tmp = 2;
|
||||
|
||||
writel(tmp, &ddr_phy->ddrphy_reg[0x28]);
|
||||
writel(tmp, &ddr_phy->ddrphy_reg[0x38]);
|
||||
writel(tmp, &ddr_phy->ddrphy_reg[0x48]);
|
||||
writel(tmp, &ddr_phy->ddrphy_reg[0x58]);
|
||||
}
|
||||
|
||||
static void send_command(struct rk322x_ddr_pctl *pctl,
|
||||
u32 rank, u32 cmd, u32 arg)
|
||||
{
|
||||
writel((START_CMD | (rank << 20) | arg | cmd), &pctl->mcmd);
|
||||
udelay(1);
|
||||
while (readl(&pctl->mcmd) & START_CMD)
|
||||
;
|
||||
}
|
||||
|
||||
static void memory_init(struct chan_info *chan,
|
||||
struct rk322x_sdram_params *sdram_params)
|
||||
{
|
||||
struct rk322x_ddr_pctl *pctl = chan->pctl;
|
||||
u32 dramtype = sdram_params->base.dramtype;
|
||||
|
||||
if (dramtype == DDR3) {
|
||||
send_command(pctl, 3, DESELECT_CMD, 0);
|
||||
udelay(1);
|
||||
send_command(pctl, 3, PREA_CMD, 0);
|
||||
send_command(pctl, 3, MRS_CMD,
|
||||
(0x02 & BANK_ADDR_MASK) << BANK_ADDR_SHIFT |
|
||||
(sdram_params->phy_timing.mr[2] & CMD_ADDR_MASK) <<
|
||||
CMD_ADDR_SHIFT);
|
||||
|
||||
send_command(pctl, 3, MRS_CMD,
|
||||
(0x03 & BANK_ADDR_MASK) << BANK_ADDR_SHIFT |
|
||||
(sdram_params->phy_timing.mr[3] & CMD_ADDR_MASK) <<
|
||||
CMD_ADDR_SHIFT);
|
||||
|
||||
send_command(pctl, 3, MRS_CMD,
|
||||
(0x01 & BANK_ADDR_MASK) << BANK_ADDR_SHIFT |
|
||||
(sdram_params->phy_timing.mr[1] & CMD_ADDR_MASK) <<
|
||||
CMD_ADDR_SHIFT);
|
||||
|
||||
send_command(pctl, 3, MRS_CMD,
|
||||
(0x00 & BANK_ADDR_MASK) << BANK_ADDR_SHIFT |
|
||||
((sdram_params->phy_timing.mr[0] |
|
||||
DDR3_DLL_RESET) &
|
||||
CMD_ADDR_MASK) << CMD_ADDR_SHIFT);
|
||||
|
||||
send_command(pctl, 3, ZQCL_CMD, 0);
|
||||
} else {
|
||||
send_command(pctl, 3, MRS_CMD,
|
||||
(0x63 & LPDDR23_MA_MASK) << LPDDR23_MA_SHIFT |
|
||||
(0 & LPDDR23_OP_MASK) <<
|
||||
LPDDR23_OP_SHIFT);
|
||||
udelay(10);
|
||||
send_command(pctl, 3, MRS_CMD,
|
||||
(0x10 & LPDDR23_MA_MASK) << LPDDR23_MA_SHIFT |
|
||||
(0xff & LPDDR23_OP_MASK) <<
|
||||
LPDDR23_OP_SHIFT);
|
||||
udelay(1);
|
||||
send_command(pctl, 3, MRS_CMD,
|
||||
(0x10 & LPDDR23_MA_MASK) << LPDDR23_MA_SHIFT |
|
||||
(0xff & LPDDR23_OP_MASK) <<
|
||||
LPDDR23_OP_SHIFT);
|
||||
udelay(1);
|
||||
send_command(pctl, 3, MRS_CMD,
|
||||
(1 & LPDDR23_MA_MASK) << LPDDR23_MA_SHIFT |
|
||||
(sdram_params->phy_timing.mr[1] &
|
||||
LPDDR23_OP_MASK) << LPDDR23_OP_SHIFT);
|
||||
send_command(pctl, 3, MRS_CMD,
|
||||
(2 & LPDDR23_MA_MASK) << LPDDR23_MA_SHIFT |
|
||||
(sdram_params->phy_timing.mr[2] &
|
||||
LPDDR23_OP_MASK) << LPDDR23_OP_SHIFT);
|
||||
send_command(pctl, 3, MRS_CMD,
|
||||
(3 & LPDDR23_MA_MASK) << LPDDR23_MA_SHIFT |
|
||||
(sdram_params->phy_timing.mr[3] &
|
||||
LPDDR23_OP_MASK) << LPDDR23_OP_SHIFT);
|
||||
if (dramtype == LPDDR3)
|
||||
send_command(pctl, 3, MRS_CMD, (11 & LPDDR23_MA_MASK) <<
|
||||
LPDDR23_MA_SHIFT |
|
||||
(sdram_params->phy_timing.mr11 &
|
||||
LPDDR23_OP_MASK) << LPDDR23_OP_SHIFT);
|
||||
}
|
||||
}
|
||||
|
||||
static u32 data_training(struct chan_info *chan)
|
||||
{
|
||||
struct rk322x_ddr_phy *ddr_phy = chan->phy;
|
||||
struct rk322x_ddr_pctl *pctl = chan->pctl;
|
||||
u32 value;
|
||||
u32 bw = (readl(&ddr_phy->ddrphy_reg[0]) >> 4) & 0xf;
|
||||
u32 ret;
|
||||
|
||||
/* disable auto refresh */
|
||||
value = readl(&pctl->trefi) | (1 << 31);
|
||||
writel(1 << 31, &pctl->trefi);
|
||||
|
||||
clrsetbits_le32(&ddr_phy->ddrphy_reg[2], 0x30,
|
||||
DQS_SQU_CAL_SEL_CS0);
|
||||
setbits_le32(&ddr_phy->ddrphy_reg[2], DQS_SQU_CAL_START);
|
||||
|
||||
udelay(30);
|
||||
ret = readl(&ddr_phy->ddrphy_reg[0xff]);
|
||||
|
||||
clrbits_le32(&ddr_phy->ddrphy_reg[2],
|
||||
DQS_SQU_CAL_START);
|
||||
|
||||
/*
|
||||
* since data training will take about 20us, so send some auto
|
||||
* refresh(about 7.8us) to complement the lost time
|
||||
*/
|
||||
send_command(pctl, 3, PREA_CMD, 0);
|
||||
send_command(pctl, 3, REF_CMD, 0);
|
||||
|
||||
writel(value, &pctl->trefi);
|
||||
|
||||
if (ret & 0x10) {
|
||||
ret = -1;
|
||||
} else {
|
||||
ret = (ret & 0xf) ^ bw;
|
||||
ret = (ret == 0) ? 0 : -1;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void move_to_config_state(struct rk322x_ddr_pctl *pctl)
|
||||
{
|
||||
unsigned int state;
|
||||
|
||||
while (1) {
|
||||
state = readl(&pctl->stat) & PCTL_STAT_MASK;
|
||||
switch (state) {
|
||||
case LOW_POWER:
|
||||
writel(WAKEUP_STATE, &pctl->sctl);
|
||||
while ((readl(&pctl->stat) & PCTL_STAT_MASK)
|
||||
!= ACCESS)
|
||||
;
|
||||
/*
|
||||
* If at low power state, need wakeup first, and then
|
||||
* enter the config, so fallthrough
|
||||
*/
|
||||
case ACCESS:
|
||||
/* fallthrough */
|
||||
case INIT_MEM:
|
||||
writel(CFG_STATE, &pctl->sctl);
|
||||
while ((readl(&pctl->stat) & PCTL_STAT_MASK) != CONFIG)
|
||||
;
|
||||
break;
|
||||
case CONFIG:
|
||||
return;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void move_to_access_state(struct rk322x_ddr_pctl *pctl)
|
||||
{
|
||||
unsigned int state;
|
||||
|
||||
while (1) {
|
||||
state = readl(&pctl->stat) & PCTL_STAT_MASK;
|
||||
switch (state) {
|
||||
case LOW_POWER:
|
||||
writel(WAKEUP_STATE, &pctl->sctl);
|
||||
while ((readl(&pctl->stat) & PCTL_STAT_MASK) != ACCESS)
|
||||
;
|
||||
break;
|
||||
case INIT_MEM:
|
||||
writel(CFG_STATE, &pctl->sctl);
|
||||
while ((readl(&pctl->stat) & PCTL_STAT_MASK) != CONFIG)
|
||||
;
|
||||
/* fallthrough */
|
||||
case CONFIG:
|
||||
writel(GO_STATE, &pctl->sctl);
|
||||
while ((readl(&pctl->stat) & PCTL_STAT_MASK) != ACCESS)
|
||||
;
|
||||
break;
|
||||
case ACCESS:
|
||||
return;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void move_to_lowpower_state(struct rk322x_ddr_pctl *pctl)
|
||||
{
|
||||
unsigned int state;
|
||||
|
||||
while (1) {
|
||||
state = readl(&pctl->stat) & PCTL_STAT_MASK;
|
||||
switch (state) {
|
||||
case INIT_MEM:
|
||||
writel(CFG_STATE, &pctl->sctl);
|
||||
while ((readl(&pctl->stat) & PCTL_STAT_MASK) != CONFIG)
|
||||
;
|
||||
/* fallthrough */
|
||||
case CONFIG:
|
||||
writel(GO_STATE, &pctl->sctl);
|
||||
while ((readl(&pctl->stat) & PCTL_STAT_MASK) != ACCESS)
|
||||
;
|
||||
break;
|
||||
case ACCESS:
|
||||
writel(SLEEP_STATE, &pctl->sctl);
|
||||
while ((readl(&pctl->stat) & PCTL_STAT_MASK) !=
|
||||
LOW_POWER)
|
||||
;
|
||||
break;
|
||||
case LOW_POWER:
|
||||
return;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* pctl should in low power mode when call this function */
|
||||
static void phy_softreset(struct dram_info *dram)
|
||||
{
|
||||
struct rk322x_ddr_phy *ddr_phy = dram->chan[0].phy;
|
||||
struct rk322x_grf *grf = dram->grf;
|
||||
|
||||
writel(GRF_DDRPHY_BUFFEREN_CORE_EN, &grf->soc_con[0]);
|
||||
clrbits_le32(&ddr_phy->ddrphy_reg[0], 0x3 << 2);
|
||||
udelay(1);
|
||||
setbits_le32(&ddr_phy->ddrphy_reg[0], 1 << 2);
|
||||
udelay(5);
|
||||
setbits_le32(&ddr_phy->ddrphy_reg[0], 1 << 3);
|
||||
writel(GRF_DDRPHY_BUFFEREN_CORE_DIS, &grf->soc_con[0]);
|
||||
}
|
||||
|
||||
/* bw: 2: 32bit, 1:16bit */
|
||||
static void set_bw(struct dram_info *dram, u32 bw)
|
||||
{
|
||||
struct rk322x_ddr_pctl *pctl = dram->chan[0].pctl;
|
||||
struct rk322x_ddr_phy *ddr_phy = dram->chan[0].phy;
|
||||
struct rk322x_grf *grf = dram->grf;
|
||||
|
||||
if (bw == 1) {
|
||||
setbits_le32(&pctl->ppcfg, 1);
|
||||
clrbits_le32(&ddr_phy->ddrphy_reg[0], 0xc << 4);
|
||||
writel(GRF_MSCH_NOC_16BIT_EN, &grf->soc_con[0]);
|
||||
clrbits_le32(&ddr_phy->ddrphy_reg[0x46], 0x8);
|
||||
clrbits_le32(&ddr_phy->ddrphy_reg[0x56], 0x8);
|
||||
} else {
|
||||
clrbits_le32(&pctl->ppcfg, 1);
|
||||
setbits_le32(&ddr_phy->ddrphy_reg[0], 0xf << 4);
|
||||
writel(GRF_DDR_32BIT_EN | GRF_MSCH_NOC_32BIT_EN,
|
||||
&grf->soc_con[0]);
|
||||
setbits_le32(&ddr_phy->ddrphy_reg[0x46], 0x8);
|
||||
setbits_le32(&ddr_phy->ddrphy_reg[0x56], 0x8);
|
||||
}
|
||||
}
|
||||
|
||||
static void pctl_cfg(struct rk322x_ddr_pctl *pctl,
|
||||
struct rk322x_sdram_params *sdram_params,
|
||||
struct rk322x_grf *grf)
|
||||
{
|
||||
u32 burst_len;
|
||||
u32 bw;
|
||||
u32 dramtype = sdram_params->base.dramtype;
|
||||
|
||||
if (sdram_params->ch[0].bw == 2)
|
||||
bw = GRF_DDR_32BIT_EN | GRF_MSCH_NOC_32BIT_EN;
|
||||
else
|
||||
bw = GRF_MSCH_NOC_16BIT_EN;
|
||||
|
||||
writel(DFI_INIT_START | DFI_DATA_BYTE_DISABLE_EN, &pctl->dfistcfg0);
|
||||
writel(DFI_DRAM_CLK_SR_EN | DFI_DRAM_CLK_DPD_EN, &pctl->dfistcfg1);
|
||||
writel(DFI_PARITY_INTR_EN | DFI_PARITY_EN, &pctl->dfistcfg2);
|
||||
writel(0x51010, &pctl->dfilpcfg0);
|
||||
|
||||
writel(1, &pctl->dfitphyupdtype0);
|
||||
writel(0x0d, &pctl->dfitphyrdlat);
|
||||
writel(0, &pctl->dfitphywrdata);
|
||||
|
||||
writel(0, &pctl->dfiupdcfg);
|
||||
copy_to_reg(&pctl->togcnt1u, &sdram_params->pctl_timing.togcnt1u,
|
||||
sizeof(struct rk322x_pctl_timing));
|
||||
if (dramtype == DDR3) {
|
||||
writel((1 << 3) | (1 << 11),
|
||||
&pctl->dfiodtcfg);
|
||||
writel(7 << 16, &pctl->dfiodtcfg1);
|
||||
writel((readl(&pctl->tcl) - 1) / 2 - 1, &pctl->dfitrddataen);
|
||||
writel((readl(&pctl->tcwl) - 1) / 2 - 1, &pctl->dfitphywrlat);
|
||||
writel(500, &pctl->trsth);
|
||||
writel(0 << MDDR_LPDDR2_CLK_STOP_IDLE_SHIFT | DDR3_EN |
|
||||
DDR2_DDR3_BL_8 | (6 - 4) << TFAW_SHIFT | PD_EXIT_SLOW |
|
||||
1 << PD_TYPE_SHIFT | 0 << PD_IDLE_SHIFT,
|
||||
&pctl->mcfg);
|
||||
writel(bw | GRF_DDR3_EN, &grf->soc_con[0]);
|
||||
} else {
|
||||
if (sdram_params->phy_timing.bl & PHT_BL_8)
|
||||
burst_len = MDDR_LPDDR2_BL_8;
|
||||
else
|
||||
burst_len = MDDR_LPDDR2_BL_4;
|
||||
|
||||
writel(readl(&pctl->tcl) / 2 - 1, &pctl->dfitrddataen);
|
||||
writel(readl(&pctl->tcwl) / 2 - 1, &pctl->dfitphywrlat);
|
||||
writel(0, &pctl->trsth);
|
||||
if (dramtype == LPDDR2) {
|
||||
writel(0 << MDDR_LPDDR2_CLK_STOP_IDLE_SHIFT |
|
||||
LPDDR2_S4 | LPDDR2_EN | burst_len |
|
||||
(6 - 4) << TFAW_SHIFT | PD_EXIT_FAST |
|
||||
1 << PD_TYPE_SHIFT | 0 << PD_IDLE_SHIFT,
|
||||
&pctl->mcfg);
|
||||
writel(0, &pctl->dfiodtcfg);
|
||||
writel(0, &pctl->dfiodtcfg1);
|
||||
} else {
|
||||
writel(0 << MDDR_LPDDR2_CLK_STOP_IDLE_SHIFT |
|
||||
LPDDR2_S4 | LPDDR3_EN | burst_len |
|
||||
(6 - 4) << TFAW_SHIFT | PD_EXIT_FAST |
|
||||
1 << PD_TYPE_SHIFT | 0 << PD_IDLE_SHIFT,
|
||||
&pctl->mcfg);
|
||||
writel((1 << 3) | (1 << 2), &pctl->dfiodtcfg);
|
||||
writel((7 << 16) | 4, &pctl->dfiodtcfg1);
|
||||
}
|
||||
writel(bw | GRF_LPDDR2_3_EN, &grf->soc_con[0]);
|
||||
}
|
||||
setbits_le32(&pctl->scfg, 1);
|
||||
}
|
||||
|
||||
static void phy_cfg(struct chan_info *chan,
|
||||
struct rk322x_sdram_params *sdram_params)
|
||||
{
|
||||
struct rk322x_ddr_phy *ddr_phy = chan->phy;
|
||||
struct rk322x_service_sys *axi_bus = chan->msch;
|
||||
struct rk322x_msch_timings *noc_timing = &sdram_params->base.noc_timing;
|
||||
struct rk322x_phy_timing *phy_timing = &sdram_params->phy_timing;
|
||||
struct rk322x_pctl_timing *pctl_timing = &sdram_params->pctl_timing;
|
||||
u32 cmd_drv, clk_drv, dqs_drv, dqs_odt;
|
||||
|
||||
writel(noc_timing->ddrtiming, &axi_bus->ddrtiming);
|
||||
writel(noc_timing->ddrmode, &axi_bus->ddrmode);
|
||||
writel(noc_timing->readlatency, &axi_bus->readlatency);
|
||||
writel(noc_timing->activate, &axi_bus->activate);
|
||||
writel(noc_timing->devtodev, &axi_bus->devtodev);
|
||||
|
||||
switch (sdram_params->base.dramtype) {
|
||||
case DDR3:
|
||||
writel(PHY_DDR3 | phy_timing->bl, &ddr_phy->ddrphy_reg[1]);
|
||||
break;
|
||||
case LPDDR2:
|
||||
writel(PHY_LPDDR2 | phy_timing->bl, &ddr_phy->ddrphy_reg[1]);
|
||||
break;
|
||||
default:
|
||||
writel(PHY_LPDDR2 | phy_timing->bl, &ddr_phy->ddrphy_reg[1]);
|
||||
break;
|
||||
}
|
||||
|
||||
writel(phy_timing->cl_al, &ddr_phy->ddrphy_reg[0xb]);
|
||||
writel(pctl_timing->tcwl, &ddr_phy->ddrphy_reg[0xc]);
|
||||
|
||||
cmd_drv = PHY_RON_RTT_34OHM;
|
||||
clk_drv = PHY_RON_RTT_45OHM;
|
||||
dqs_drv = PHY_RON_RTT_34OHM;
|
||||
if (sdram_params->base.dramtype == LPDDR2)
|
||||
dqs_odt = PHY_RON_RTT_DISABLE;
|
||||
else
|
||||
dqs_odt = PHY_RON_RTT_225OHM;
|
||||
|
||||
writel(cmd_drv, &ddr_phy->ddrphy_reg[0x11]);
|
||||
clrsetbits_le32(&ddr_phy->ddrphy_reg[0x12], (0x1f << 3), cmd_drv << 3);
|
||||
writel(clk_drv, &ddr_phy->ddrphy_reg[0x16]);
|
||||
writel(clk_drv, &ddr_phy->ddrphy_reg[0x18]);
|
||||
|
||||
writel(dqs_drv, &ddr_phy->ddrphy_reg[0x20]);
|
||||
writel(dqs_drv, &ddr_phy->ddrphy_reg[0x2f]);
|
||||
writel(dqs_drv, &ddr_phy->ddrphy_reg[0x30]);
|
||||
writel(dqs_drv, &ddr_phy->ddrphy_reg[0x3f]);
|
||||
writel(dqs_drv, &ddr_phy->ddrphy_reg[0x40]);
|
||||
writel(dqs_drv, &ddr_phy->ddrphy_reg[0x4f]);
|
||||
writel(dqs_drv, &ddr_phy->ddrphy_reg[0x50]);
|
||||
writel(dqs_drv, &ddr_phy->ddrphy_reg[0x5f]);
|
||||
|
||||
writel(dqs_odt, &ddr_phy->ddrphy_reg[0x21]);
|
||||
writel(dqs_odt, &ddr_phy->ddrphy_reg[0x2e]);
|
||||
writel(dqs_odt, &ddr_phy->ddrphy_reg[0x31]);
|
||||
writel(dqs_odt, &ddr_phy->ddrphy_reg[0x3e]);
|
||||
writel(dqs_odt, &ddr_phy->ddrphy_reg[0x41]);
|
||||
writel(dqs_odt, &ddr_phy->ddrphy_reg[0x4e]);
|
||||
writel(dqs_odt, &ddr_phy->ddrphy_reg[0x51]);
|
||||
writel(dqs_odt, &ddr_phy->ddrphy_reg[0x5e]);
|
||||
}
|
||||
|
||||
void dram_cfg_rbc(struct chan_info *chan,
|
||||
struct rk322x_sdram_params *sdram_params)
|
||||
{
|
||||
char noc_config;
|
||||
int i = 0;
|
||||
struct rk322x_sdram_channel *config = &sdram_params->ch[0];
|
||||
struct rk322x_service_sys *axi_bus = chan->msch;
|
||||
|
||||
move_to_config_state(chan->pctl);
|
||||
|
||||
if ((config->rank == 2) && (config->cs1_row == config->cs0_row)) {
|
||||
if ((config->col + config->bw) == 12) {
|
||||
i = 14;
|
||||
goto finish;
|
||||
} else if ((config->col + config->bw) == 11) {
|
||||
i = 15;
|
||||
goto finish;
|
||||
}
|
||||
}
|
||||
noc_config = ((config->cs0_row - 13) << 4) | ((config->bk - 2) << 2) |
|
||||
(config->col + config->bw - 11);
|
||||
for (i = 0; i < 11; i++) {
|
||||
if (noc_config == ddr_cfg_2_rbc[i])
|
||||
break;
|
||||
}
|
||||
|
||||
if (i < 11)
|
||||
goto finish;
|
||||
|
||||
noc_config = ((config->bk - 2) << 6) | ((config->cs0_row - 13) << 4) |
|
||||
(config->col + config->bw - 11);
|
||||
|
||||
for (i = 11; i < 14; i++) {
|
||||
if (noc_config == ddr_cfg_2_rbc[i])
|
||||
break;
|
||||
}
|
||||
if (i < 14)
|
||||
goto finish;
|
||||
else
|
||||
i = 0;
|
||||
|
||||
finish:
|
||||
writel(i, &axi_bus->ddrconf);
|
||||
move_to_access_state(chan->pctl);
|
||||
}
|
||||
|
||||
static void dram_all_config(const struct dram_info *dram,
|
||||
struct rk322x_sdram_params *sdram_params)
|
||||
{
|
||||
struct rk322x_sdram_channel *info = &sdram_params->ch[0];
|
||||
u32 sys_reg = 0;
|
||||
|
||||
sys_reg |= sdram_params->base.dramtype << SYS_REG_DDRTYPE_SHIFT;
|
||||
sys_reg |= (1 - 1) << SYS_REG_NUM_CH_SHIFT;
|
||||
sys_reg |= info->row_3_4 << SYS_REG_ROW_3_4_SHIFT(0);
|
||||
sys_reg |= 1 << SYS_REG_CHINFO_SHIFT(0);
|
||||
sys_reg |= (info->rank - 1) << SYS_REG_RANK_SHIFT(0);
|
||||
sys_reg |= (info->col - 9) << SYS_REG_COL_SHIFT(0);
|
||||
sys_reg |= info->bk == 3 ? 0 : 1 << SYS_REG_BK_SHIFT(0);
|
||||
sys_reg |= (info->cs0_row - 13) << SYS_REG_CS0_ROW_SHIFT(0);
|
||||
sys_reg |= (info->cs1_row - 13) << SYS_REG_CS1_ROW_SHIFT(0);
|
||||
sys_reg |= (2 >> info->bw) << SYS_REG_BW_SHIFT(0);
|
||||
sys_reg |= (2 >> info->dbw) << SYS_REG_DBW_SHIFT(0);
|
||||
|
||||
writel(sys_reg, &dram->grf->os_reg[2]);
|
||||
}
|
||||
|
||||
#define TEST_PATTEN 0x5aa5f00f
|
||||
|
||||
static int dram_cap_detect(struct dram_info *dram,
|
||||
struct rk322x_sdram_params *sdram_params)
|
||||
{
|
||||
u32 bw, row, col, addr;
|
||||
u32 ret = 0;
|
||||
struct rk322x_service_sys *axi_bus = dram->chan[0].msch;
|
||||
|
||||
if (sdram_params->base.dramtype == DDR3)
|
||||
sdram_params->ch[0].dbw = 1;
|
||||
else
|
||||
sdram_params->ch[0].dbw = 2;
|
||||
|
||||
move_to_config_state(dram->chan[0].pctl);
|
||||
/* bw detect */
|
||||
set_bw(dram, 2);
|
||||
if (data_training(&dram->chan[0]) == 0) {
|
||||
bw = 2;
|
||||
} else {
|
||||
bw = 1;
|
||||
set_bw(dram, 1);
|
||||
move_to_lowpower_state(dram->chan[0].pctl);
|
||||
phy_softreset(dram);
|
||||
move_to_config_state(dram->chan[0].pctl);
|
||||
if (data_training(&dram->chan[0])) {
|
||||
printf("BW detect error\n");
|
||||
ret = -EINVAL;
|
||||
}
|
||||
}
|
||||
sdram_params->ch[0].bw = bw;
|
||||
sdram_params->ch[0].bk = 3;
|
||||
|
||||
if (bw == 2)
|
||||
writel(6, &axi_bus->ddrconf);
|
||||
else
|
||||
writel(3, &axi_bus->ddrconf);
|
||||
move_to_access_state(dram->chan[0].pctl);
|
||||
for (col = 11; col >= 9; col--) {
|
||||
writel(0, CONFIG_SYS_SDRAM_BASE);
|
||||
addr = CONFIG_SYS_SDRAM_BASE +
|
||||
(1 << (col + bw - 1));
|
||||
writel(TEST_PATTEN, addr);
|
||||
if ((readl(addr) == TEST_PATTEN) &&
|
||||
(readl(CONFIG_SYS_SDRAM_BASE) == 0))
|
||||
break;
|
||||
}
|
||||
if (col == 8) {
|
||||
printf("Col detect error\n");
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
} else {
|
||||
sdram_params->ch[0].col = col;
|
||||
}
|
||||
|
||||
writel(10, &axi_bus->ddrconf);
|
||||
|
||||
/* Detect row*/
|
||||
for (row = 16; row >= 12; row--) {
|
||||
writel(0, CONFIG_SYS_SDRAM_BASE);
|
||||
addr = CONFIG_SYS_SDRAM_BASE + (1u << (row + 11 + 3 - 1));
|
||||
writel(TEST_PATTEN, addr);
|
||||
if ((readl(addr) == TEST_PATTEN) &&
|
||||
(readl(CONFIG_SYS_SDRAM_BASE) == 0))
|
||||
break;
|
||||
}
|
||||
if (row == 11) {
|
||||
printf("Row detect error\n");
|
||||
ret = -EINVAL;
|
||||
} else {
|
||||
sdram_params->ch[0].cs1_row = row;
|
||||
sdram_params->ch[0].row_3_4 = 0;
|
||||
sdram_params->ch[0].cs0_row = row;
|
||||
}
|
||||
/* cs detect */
|
||||
writel(0, CONFIG_SYS_SDRAM_BASE);
|
||||
writel(TEST_PATTEN, CONFIG_SYS_SDRAM_BASE + (1u << 30));
|
||||
writel(~TEST_PATTEN, CONFIG_SYS_SDRAM_BASE + (1u << 30) + 4);
|
||||
if ((readl(CONFIG_SYS_SDRAM_BASE + (1u << 30)) == TEST_PATTEN) &&
|
||||
(readl(CONFIG_SYS_SDRAM_BASE) == 0))
|
||||
sdram_params->ch[0].rank = 2;
|
||||
else
|
||||
sdram_params->ch[0].rank = 1;
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int sdram_init(struct dram_info *dram,
|
||||
struct rk322x_sdram_params *sdram_params)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = clk_set_rate(&dram->ddr_clk,
|
||||
sdram_params->base.ddr_freq * MHz * 2);
|
||||
if (ret < 0) {
|
||||
printf("Could not set DDR clock\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
phy_pctrl_reset(dram->cru, dram->chan[0].phy);
|
||||
phy_dll_bypass_set(dram->chan[0].phy, sdram_params->base.ddr_freq);
|
||||
pctl_cfg(dram->chan[0].pctl, sdram_params, dram->grf);
|
||||
phy_cfg(&dram->chan[0], sdram_params);
|
||||
writel(POWER_UP_START, &dram->chan[0].pctl->powctl);
|
||||
while (!(readl(&dram->chan[0].pctl->powstat) & POWER_UP_DONE))
|
||||
;
|
||||
memory_init(&dram->chan[0], sdram_params);
|
||||
move_to_access_state(dram->chan[0].pctl);
|
||||
ret = dram_cap_detect(dram, sdram_params);
|
||||
if (ret)
|
||||
goto out;
|
||||
dram_cfg_rbc(&dram->chan[0], sdram_params);
|
||||
dram_all_config(dram, sdram_params);
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int rk322x_dmc_ofdata_to_platdata(struct udevice *dev)
|
||||
{
|
||||
#if !CONFIG_IS_ENABLED(OF_PLATDATA)
|
||||
struct rk322x_sdram_params *params = dev_get_platdata(dev);
|
||||
const void *blob = gd->fdt_blob;
|
||||
int node = dev_of_offset(dev);
|
||||
int ret;
|
||||
|
||||
params->num_channels = 1;
|
||||
|
||||
ret = fdtdec_get_int_array(blob, node, "rockchip,pctl-timing",
|
||||
(u32 *)¶ms->pctl_timing,
|
||||
sizeof(params->pctl_timing) / sizeof(u32));
|
||||
if (ret) {
|
||||
printf("%s: Cannot read rockchip,pctl-timing\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
ret = fdtdec_get_int_array(blob, node, "rockchip,phy-timing",
|
||||
(u32 *)¶ms->phy_timing,
|
||||
sizeof(params->phy_timing) / sizeof(u32));
|
||||
if (ret) {
|
||||
printf("%s: Cannot read rockchip,phy-timing\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
ret = fdtdec_get_int_array(blob, node, "rockchip,sdram-params",
|
||||
(u32 *)¶ms->base,
|
||||
sizeof(params->base) / sizeof(u32));
|
||||
if (ret) {
|
||||
printf("%s: Cannot read rockchip,sdram-params\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
ret = regmap_init_mem(dev_ofnode(dev), ¶ms->map);
|
||||
if (ret)
|
||||
return ret;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_TPL_BUILD */
|
||||
|
||||
#if CONFIG_IS_ENABLED(OF_PLATDATA)
|
||||
static int conv_of_platdata(struct udevice *dev)
|
||||
{
|
||||
struct rk322x_sdram_params *plat = dev_get_platdata(dev);
|
||||
struct dtd_rockchip_rk322x_dmc *of_plat = &plat->of_plat;
|
||||
int ret;
|
||||
|
||||
memcpy(&plat->pctl_timing, of_plat->rockchip_pctl_timing,
|
||||
sizeof(plat->pctl_timing));
|
||||
memcpy(&plat->phy_timing, of_plat->rockchip_phy_timing,
|
||||
sizeof(plat->phy_timing));
|
||||
memcpy(&plat->base, of_plat->rockchip_sdram_params, sizeof(plat->base));
|
||||
|
||||
plat->num_channels = 1;
|
||||
ret = regmap_init_mem_platdata(dev, of_plat->reg,
|
||||
ARRAY_SIZE(of_plat->reg) / 2,
|
||||
&plat->map);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int rk322x_dmc_probe(struct udevice *dev)
|
||||
{
|
||||
#ifdef CONFIG_TPL_BUILD
|
||||
struct rk322x_sdram_params *plat = dev_get_platdata(dev);
|
||||
int ret;
|
||||
struct udevice *dev_clk;
|
||||
#endif
|
||||
struct dram_info *priv = dev_get_priv(dev);
|
||||
|
||||
priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
|
||||
#ifdef CONFIG_TPL_BUILD
|
||||
#if CONFIG_IS_ENABLED(OF_PLATDATA)
|
||||
ret = conv_of_platdata(dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
#endif
|
||||
|
||||
priv->chan[0].msch = syscon_get_first_range(ROCKCHIP_SYSCON_MSCH);
|
||||
priv->chan[0].pctl = regmap_get_range(plat->map, 0);
|
||||
priv->chan[0].phy = regmap_get_range(plat->map, 1);
|
||||
ret = rockchip_get_clk(&dev_clk);
|
||||
if (ret)
|
||||
return ret;
|
||||
priv->ddr_clk.id = CLK_DDR;
|
||||
ret = clk_request(dev_clk, &priv->ddr_clk);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
priv->cru = rockchip_get_cru();
|
||||
if (IS_ERR(priv->cru))
|
||||
return PTR_ERR(priv->cru);
|
||||
ret = sdram_init(priv, plat);
|
||||
if (ret)
|
||||
return ret;
|
||||
#else
|
||||
priv->info.base = CONFIG_SYS_SDRAM_BASE;
|
||||
priv->info.size = rockchip_sdram_size(
|
||||
(phys_addr_t)&priv->grf->os_reg[2]);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rk322x_dmc_get_info(struct udevice *dev, struct ram_info *info)
|
||||
{
|
||||
struct dram_info *priv = dev_get_priv(dev);
|
||||
|
||||
*info = priv->info;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct ram_ops rk322x_dmc_ops = {
|
||||
.get_info = rk322x_dmc_get_info,
|
||||
};
|
||||
|
||||
static const struct udevice_id rk322x_dmc_ids[] = {
|
||||
{ .compatible = "rockchip,rk3228-dmc" },
|
||||
{ }
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(dmc_rk322x) = {
|
||||
.name = "rockchip_rk322x_dmc",
|
||||
.id = UCLASS_RAM,
|
||||
.of_match = rk322x_dmc_ids,
|
||||
.ops = &rk322x_dmc_ops,
|
||||
#ifdef CONFIG_TPL_BUILD
|
||||
.ofdata_to_platdata = rk322x_dmc_ofdata_to_platdata,
|
||||
#endif
|
||||
.probe = rk322x_dmc_probe,
|
||||
.priv_auto_alloc_size = sizeof(struct dram_info),
|
||||
#ifdef CONFIG_TPL_BUILD
|
||||
.platdata_auto_alloc_size = sizeof(struct rk322x_sdram_params),
|
||||
#endif
|
||||
};
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,55 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
|
||||
/*
|
||||
* (C) Copyright 2019 Rockchip Electronics Co., Ltd.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <ram.h>
|
||||
#include <syscon.h>
|
||||
#include <asm/arch/grf_rk3308.h>
|
||||
#include <asm/arch-rockchip/clock.h>
|
||||
#include <asm/arch-rockchip/sdram.h>
|
||||
|
||||
struct dram_info {
|
||||
struct ram_info info;
|
||||
struct rk3308_grf *grf;
|
||||
};
|
||||
|
||||
static int rk3308_dmc_probe(struct udevice *dev)
|
||||
{
|
||||
struct dram_info *priv = dev_get_priv(dev);
|
||||
|
||||
priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
|
||||
priv->info.base = CONFIG_SYS_SDRAM_BASE;
|
||||
priv->info.size = rockchip_sdram_size((phys_addr_t)&priv->grf->os_reg2);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rk3308_dmc_get_info(struct udevice *dev, struct ram_info *info)
|
||||
{
|
||||
struct dram_info *priv = dev_get_priv(dev);
|
||||
|
||||
*info = priv->info;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct ram_ops rk3308_dmc_ops = {
|
||||
.get_info = rk3308_dmc_get_info,
|
||||
};
|
||||
|
||||
static const struct udevice_id rk3308_dmc_ids[] = {
|
||||
{ .compatible = "rockchip,rk3308-dmc" },
|
||||
{ }
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(dmc_rk3308) = {
|
||||
.name = "rockchip_rk3308_dmc",
|
||||
.id = UCLASS_RAM,
|
||||
.of_match = rk3308_dmc_ids,
|
||||
.ops = &rk3308_dmc_ops,
|
||||
.probe = rk3308_dmc_probe,
|
||||
.priv_auto_alloc_size = sizeof(struct dram_info),
|
||||
};
|
||||
@@ -0,0 +1,623 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
|
||||
/*
|
||||
* (C) Copyright 2017 Rockchip Electronics Co., Ltd.
|
||||
*/
|
||||
#include <common.h>
|
||||
#include <clk.h>
|
||||
#include <debug_uart.h>
|
||||
#include <dm.h>
|
||||
#include <dt-structs.h>
|
||||
#include <ram.h>
|
||||
#include <regmap.h>
|
||||
#include <syscon.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/arch-rockchip/clock.h>
|
||||
#include <asm/arch-rockchip/cru_rk3328.h>
|
||||
#include <asm/arch-rockchip/grf_rk3328.h>
|
||||
#include <asm/arch-rockchip/sdram.h>
|
||||
#include <asm/arch-rockchip/sdram_rk3328.h>
|
||||
#include <asm/arch-rockchip/uart.h>
|
||||
|
||||
struct dram_info {
|
||||
#ifdef CONFIG_TPL_BUILD
|
||||
struct ddr_pctl_regs *pctl;
|
||||
struct ddr_phy_regs *phy;
|
||||
struct clk ddr_clk;
|
||||
struct rk3328_cru *cru;
|
||||
struct msch_regs *msch;
|
||||
struct rk3328_ddr_grf_regs *ddr_grf;
|
||||
#endif
|
||||
struct ram_info info;
|
||||
struct rk3328_grf_regs *grf;
|
||||
};
|
||||
|
||||
#ifdef CONFIG_TPL_BUILD
|
||||
|
||||
struct rk3328_sdram_channel sdram_ch;
|
||||
|
||||
struct rockchip_dmc_plat {
|
||||
#if CONFIG_IS_ENABLED(OF_PLATDATA)
|
||||
struct dtd_rockchip_rk3328_dmc dtplat;
|
||||
#else
|
||||
struct rk3328_sdram_params sdram_params;
|
||||
#endif
|
||||
struct regmap *map;
|
||||
};
|
||||
|
||||
#if CONFIG_IS_ENABLED(OF_PLATDATA)
|
||||
static int conv_of_platdata(struct udevice *dev)
|
||||
{
|
||||
struct rockchip_dmc_plat *plat = dev_get_platdata(dev);
|
||||
struct dtd_rockchip_rk3328_dmc *dtplat = &plat->dtplat;
|
||||
int ret;
|
||||
|
||||
ret = regmap_init_mem_platdata(dev, dtplat->reg,
|
||||
ARRAY_SIZE(dtplat->reg) / 2,
|
||||
&plat->map);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void rkclk_ddr_reset(struct dram_info *dram,
|
||||
u32 ctl_srstn, u32 ctl_psrstn,
|
||||
u32 phy_srstn, u32 phy_psrstn)
|
||||
{
|
||||
writel(ddrctrl_srstn_req(ctl_srstn) | ddrctrl_psrstn_req(ctl_psrstn) |
|
||||
ddrphy_srstn_req(phy_srstn) | ddrphy_psrstn_req(phy_psrstn),
|
||||
&dram->cru->softrst_con[5]);
|
||||
writel(ddrctrl_asrstn_req(ctl_srstn), &dram->cru->softrst_con[9]);
|
||||
}
|
||||
|
||||
static void rkclk_set_dpll(struct dram_info *dram, unsigned int hz)
|
||||
{
|
||||
unsigned int refdiv, postdiv1, postdiv2, fbdiv;
|
||||
int delay = 1000;
|
||||
u32 mhz = hz / MHZ;
|
||||
|
||||
refdiv = 1;
|
||||
if (mhz <= 300) {
|
||||
postdiv1 = 4;
|
||||
postdiv2 = 2;
|
||||
} else if (mhz <= 400) {
|
||||
postdiv1 = 6;
|
||||
postdiv2 = 1;
|
||||
} else if (mhz <= 600) {
|
||||
postdiv1 = 4;
|
||||
postdiv2 = 1;
|
||||
} else if (mhz <= 800) {
|
||||
postdiv1 = 3;
|
||||
postdiv2 = 1;
|
||||
} else if (mhz <= 1600) {
|
||||
postdiv1 = 2;
|
||||
postdiv2 = 1;
|
||||
} else {
|
||||
postdiv1 = 1;
|
||||
postdiv2 = 1;
|
||||
}
|
||||
fbdiv = (mhz * refdiv * postdiv1 * postdiv2) / 24;
|
||||
|
||||
writel(((0x1 << 4) << 16) | (0 << 4), &dram->cru->mode_con);
|
||||
writel(POSTDIV1(postdiv1) | FBDIV(fbdiv), &dram->cru->dpll_con[0]);
|
||||
writel(DSMPD(1) | POSTDIV2(postdiv2) | REFDIV(refdiv),
|
||||
&dram->cru->dpll_con[1]);
|
||||
|
||||
while (delay > 0) {
|
||||
udelay(1);
|
||||
if (LOCK(readl(&dram->cru->dpll_con[1])))
|
||||
break;
|
||||
delay--;
|
||||
}
|
||||
|
||||
writel(((0x1 << 4) << 16) | (1 << 4), &dram->cru->mode_con);
|
||||
}
|
||||
|
||||
static void rkclk_configure_ddr(struct dram_info *dram,
|
||||
struct rk3328_sdram_params *sdram_params)
|
||||
{
|
||||
void __iomem *phy_base = dram->phy;
|
||||
|
||||
/* choose DPLL for ddr clk source */
|
||||
clrbits_le32(PHY_REG(phy_base, 0xef), 1 << 7);
|
||||
|
||||
/* for inno ddr phy need 2*freq */
|
||||
rkclk_set_dpll(dram, sdram_params->base.ddr_freq * MHZ * 2);
|
||||
}
|
||||
|
||||
/* return ddrconfig value
|
||||
* (-1), find ddrconfig fail
|
||||
* other, the ddrconfig value
|
||||
* only support cs0_row >= cs1_row
|
||||
*/
|
||||
static u32 calculate_ddrconfig(struct rk3328_sdram_params *sdram_params)
|
||||
{
|
||||
struct sdram_cap_info *cap_info = &sdram_params->ch.cap_info;
|
||||
u32 cs, bw, die_bw, col, row, bank;
|
||||
u32 cs1_row;
|
||||
u32 i, tmp;
|
||||
u32 ddrconf = -1;
|
||||
|
||||
cs = cap_info->rank;
|
||||
bw = cap_info->bw;
|
||||
die_bw = cap_info->dbw;
|
||||
col = cap_info->col;
|
||||
row = cap_info->cs0_row;
|
||||
cs1_row = cap_info->cs1_row;
|
||||
bank = cap_info->bk;
|
||||
|
||||
if (sdram_params->base.dramtype == DDR4) {
|
||||
/* when DDR_TEST, CS always at MSB position for easy test */
|
||||
if (cs == 2 && row == cs1_row) {
|
||||
/* include 2cs cap both 2^n or both (2^n - 2^(n-2)) */
|
||||
tmp = ((row - 13) << 3) | (1 << 2) | (bw & 0x2) |
|
||||
die_bw;
|
||||
for (i = 17; i < 21; i++) {
|
||||
if (((tmp & 0x7) ==
|
||||
(ddr4_cfg_2_rbc[i - 10] & 0x7)) &&
|
||||
((tmp & 0x3c) <=
|
||||
(ddr4_cfg_2_rbc[i - 10] & 0x3c))) {
|
||||
ddrconf = i;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tmp = ((cs - 1) << 6) | ((row - 13) << 3) | (bw & 0x2) | die_bw;
|
||||
for (i = 10; i < 17; i++) {
|
||||
if (((tmp & 0x7) == (ddr4_cfg_2_rbc[i - 10] & 0x7)) &&
|
||||
((tmp & 0x3c) <= (ddr4_cfg_2_rbc[i - 10] & 0x3c)) &&
|
||||
((tmp & 0x40) <= (ddr4_cfg_2_rbc[i - 10] & 0x40))) {
|
||||
ddrconf = i;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (bank == 2) {
|
||||
ddrconf = 8;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* when DDR_TEST, CS always at MSB position for easy test */
|
||||
if (cs == 2 && row == cs1_row) {
|
||||
/* include 2cs cap both 2^n or both (2^n - 2^(n-2)) */
|
||||
for (i = 5; i < 8; i++) {
|
||||
if ((bw + col - 11) == (ddr_cfg_2_rbc[i] &
|
||||
0x3)) {
|
||||
ddrconf = i;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tmp = ((row - 13) << 4) | (1 << 2) | ((bw + col - 11) << 0);
|
||||
for (i = 0; i < 5; i++)
|
||||
if (((tmp & 0xf) == (ddr_cfg_2_rbc[i] & 0xf)) &&
|
||||
((tmp & 0x30) <= (ddr_cfg_2_rbc[i] & 0x30))) {
|
||||
ddrconf = i;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
if (ddrconf > 20)
|
||||
printf("calculate ddrconfig error\n");
|
||||
|
||||
return ddrconf;
|
||||
}
|
||||
|
||||
/*******
|
||||
* calculate controller dram address map, and setting to register.
|
||||
* argument sdram_ch.ddrconf must be right value before
|
||||
* call this function.
|
||||
*******/
|
||||
static void set_ctl_address_map(struct dram_info *dram,
|
||||
struct rk3328_sdram_params *sdram_params)
|
||||
{
|
||||
struct sdram_cap_info *cap_info = &sdram_params->ch.cap_info;
|
||||
void __iomem *pctl_base = dram->pctl;
|
||||
|
||||
sdram_copy_to_reg((u32 *)(pctl_base + DDR_PCTL2_ADDRMAP0),
|
||||
&addrmap[cap_info->ddrconfig][0], 9 * 4);
|
||||
if (sdram_params->base.dramtype == LPDDR3 && cap_info->row_3_4)
|
||||
setbits_le32(pctl_base + DDR_PCTL2_ADDRMAP6, 1 << 31);
|
||||
if (sdram_params->base.dramtype == DDR4 && cap_info->bw == 0x1)
|
||||
setbits_le32(pctl_base + DDR_PCTL2_PCCFG, 1 << 8);
|
||||
|
||||
if (cap_info->rank == 1)
|
||||
clrsetbits_le32(pctl_base + DDR_PCTL2_ADDRMAP0, 0x1f, 0x1f);
|
||||
}
|
||||
|
||||
static int data_training(struct dram_info *dram, u32 cs, u32 dramtype)
|
||||
{
|
||||
void __iomem *pctl_base = dram->pctl;
|
||||
u32 dis_auto_zq = 0;
|
||||
u32 pwrctl;
|
||||
u32 ret;
|
||||
|
||||
/* disable auto low-power */
|
||||
pwrctl = readl(pctl_base + DDR_PCTL2_PWRCTL);
|
||||
writel(0, pctl_base + DDR_PCTL2_PWRCTL);
|
||||
|
||||
dis_auto_zq = pctl_dis_zqcs_aref(dram->pctl);
|
||||
|
||||
ret = phy_data_training(dram->phy, cs, dramtype);
|
||||
|
||||
pctl_rest_zqcs_aref(dram->pctl, dis_auto_zq);
|
||||
|
||||
/* restore auto low-power */
|
||||
writel(pwrctl, pctl_base + DDR_PCTL2_PWRCTL);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void rx_deskew_switch_adjust(struct dram_info *dram)
|
||||
{
|
||||
u32 i, deskew_val;
|
||||
u32 gate_val = 0;
|
||||
void __iomem *phy_base = dram->phy;
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
gate_val = MAX(readl(PHY_REG(phy_base, 0xfb + i)), gate_val);
|
||||
|
||||
deskew_val = (gate_val >> 3) + 1;
|
||||
deskew_val = (deskew_val > 0x1f) ? 0x1f : deskew_val;
|
||||
clrsetbits_le32(PHY_REG(phy_base, 0x6e), 0xc, (deskew_val & 0x3) << 2);
|
||||
clrsetbits_le32(PHY_REG(phy_base, 0x6f), 0x7 << 4,
|
||||
(deskew_val & 0x1c) << 2);
|
||||
}
|
||||
|
||||
static void tx_deskew_switch_adjust(struct dram_info *dram)
|
||||
{
|
||||
void __iomem *phy_base = dram->phy;
|
||||
|
||||
clrsetbits_le32(PHY_REG(phy_base, 0x6e), 0x3, 1);
|
||||
}
|
||||
|
||||
static void set_ddrconfig(struct dram_info *dram, u32 ddrconfig)
|
||||
{
|
||||
writel(ddrconfig, &dram->msch->ddrconf);
|
||||
}
|
||||
|
||||
static void sdram_msch_config(struct msch_regs *msch,
|
||||
struct sdram_msch_timings *noc_timings)
|
||||
{
|
||||
writel(noc_timings->ddrtiming.d32, &msch->ddrtiming);
|
||||
|
||||
writel(noc_timings->ddrmode.d32, &msch->ddrmode);
|
||||
writel(noc_timings->readlatency, &msch->readlatency);
|
||||
|
||||
writel(noc_timings->activate.d32, &msch->activate);
|
||||
writel(noc_timings->devtodev.d32, &msch->devtodev);
|
||||
writel(noc_timings->ddr4timing.d32, &msch->ddr4_timing);
|
||||
writel(noc_timings->agingx0, &msch->aging0);
|
||||
writel(noc_timings->agingx0, &msch->aging1);
|
||||
writel(noc_timings->agingx0, &msch->aging2);
|
||||
writel(noc_timings->agingx0, &msch->aging3);
|
||||
writel(noc_timings->agingx0, &msch->aging4);
|
||||
writel(noc_timings->agingx0, &msch->aging5);
|
||||
}
|
||||
|
||||
static void dram_all_config(struct dram_info *dram,
|
||||
struct rk3328_sdram_params *sdram_params)
|
||||
{
|
||||
struct sdram_cap_info *cap_info = &sdram_params->ch.cap_info;
|
||||
u32 sys_reg2 = 0;
|
||||
u32 sys_reg3 = 0;
|
||||
|
||||
set_ddrconfig(dram, cap_info->ddrconfig);
|
||||
sdram_org_config(cap_info, &sdram_params->base, &sys_reg2,
|
||||
&sys_reg3, 0);
|
||||
writel(sys_reg2, &dram->grf->os_reg[2]);
|
||||
writel(sys_reg3, &dram->grf->os_reg[3]);
|
||||
|
||||
sdram_msch_config(dram->msch, &sdram_ch.noc_timings);
|
||||
}
|
||||
|
||||
static void enable_low_power(struct dram_info *dram,
|
||||
struct rk3328_sdram_params *sdram_params)
|
||||
{
|
||||
void __iomem *pctl_base = dram->pctl;
|
||||
|
||||
/* enable upctl2 axi clock auto gating */
|
||||
writel(0x00800000, &dram->ddr_grf->ddr_grf_con[0]);
|
||||
writel(0x20012001, &dram->ddr_grf->ddr_grf_con[2]);
|
||||
/* enable upctl2 core clock auto gating */
|
||||
writel(0x001e001a, &dram->ddr_grf->ddr_grf_con[2]);
|
||||
/* enable sr, pd */
|
||||
if (PD_IDLE == 0)
|
||||
clrbits_le32(pctl_base + DDR_PCTL2_PWRCTL, (1 << 1));
|
||||
else
|
||||
setbits_le32(pctl_base + DDR_PCTL2_PWRCTL, (1 << 1));
|
||||
if (SR_IDLE == 0)
|
||||
clrbits_le32(pctl_base + DDR_PCTL2_PWRCTL, 1);
|
||||
else
|
||||
setbits_le32(pctl_base + DDR_PCTL2_PWRCTL, 1);
|
||||
setbits_le32(pctl_base + DDR_PCTL2_PWRCTL, (1 << 3));
|
||||
}
|
||||
|
||||
static int sdram_init(struct dram_info *dram,
|
||||
struct rk3328_sdram_params *sdram_params, u32 pre_init)
|
||||
{
|
||||
struct sdram_cap_info *cap_info = &sdram_params->ch.cap_info;
|
||||
void __iomem *pctl_base = dram->pctl;
|
||||
|
||||
rkclk_ddr_reset(dram, 1, 1, 1, 1);
|
||||
udelay(10);
|
||||
/*
|
||||
* dereset ddr phy psrstn to config pll,
|
||||
* if using phy pll psrstn must be dereset
|
||||
* before config pll
|
||||
*/
|
||||
rkclk_ddr_reset(dram, 1, 1, 1, 0);
|
||||
rkclk_configure_ddr(dram, sdram_params);
|
||||
|
||||
/* release phy srst to provide clk to ctrl */
|
||||
rkclk_ddr_reset(dram, 1, 1, 0, 0);
|
||||
udelay(10);
|
||||
phy_soft_reset(dram->phy);
|
||||
/* release ctrl presetn, and config ctl registers */
|
||||
rkclk_ddr_reset(dram, 1, 0, 0, 0);
|
||||
pctl_cfg(dram->pctl, &sdram_params->pctl_regs, SR_IDLE, PD_IDLE);
|
||||
cap_info->ddrconfig = calculate_ddrconfig(sdram_params);
|
||||
set_ctl_address_map(dram, sdram_params);
|
||||
phy_cfg(dram->phy, &sdram_params->phy_regs, &sdram_params->skew,
|
||||
&sdram_params->base, cap_info->bw);
|
||||
|
||||
/* enable dfi_init_start to init phy after ctl srstn deassert */
|
||||
setbits_le32(pctl_base + DDR_PCTL2_DFIMISC, (1 << 5) | (1 << 4));
|
||||
rkclk_ddr_reset(dram, 0, 0, 0, 0);
|
||||
/* wait for dfi_init_done and dram init complete */
|
||||
while ((readl(pctl_base + DDR_PCTL2_STAT) & 0x7) == 0)
|
||||
continue;
|
||||
|
||||
/* do ddr gate training */
|
||||
if (data_training(dram, 0, sdram_params->base.dramtype) != 0) {
|
||||
printf("data training error\n");
|
||||
return -1;
|
||||
}
|
||||
if (data_training(dram, 1, sdram_params->base.dramtype) != 0) {
|
||||
printf("data training error\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (sdram_params->base.dramtype == DDR4)
|
||||
pctl_write_vrefdq(dram->pctl, 0x3, 5670,
|
||||
sdram_params->base.dramtype);
|
||||
|
||||
if (pre_init == 0) {
|
||||
rx_deskew_switch_adjust(dram);
|
||||
tx_deskew_switch_adjust(dram);
|
||||
}
|
||||
|
||||
dram_all_config(dram, sdram_params);
|
||||
enable_low_power(dram, sdram_params);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static u64 dram_detect_cap(struct dram_info *dram,
|
||||
struct rk3328_sdram_params *sdram_params,
|
||||
unsigned char channel)
|
||||
{
|
||||
struct sdram_cap_info *cap_info = &sdram_params->ch.cap_info;
|
||||
|
||||
/*
|
||||
* for ddr3: ddrconf = 3
|
||||
* for ddr4: ddrconf = 12
|
||||
* for lpddr3: ddrconf = 3
|
||||
* default bw = 1
|
||||
*/
|
||||
u32 bk, bktmp;
|
||||
u32 col, coltmp;
|
||||
u32 rowtmp;
|
||||
u32 cs;
|
||||
u32 bw = 1;
|
||||
u32 dram_type = sdram_params->base.dramtype;
|
||||
|
||||
if (dram_type != DDR4) {
|
||||
/* detect col and bk for ddr3/lpddr3 */
|
||||
coltmp = 12;
|
||||
bktmp = 3;
|
||||
rowtmp = 16;
|
||||
|
||||
if (sdram_detect_col(cap_info, coltmp) != 0)
|
||||
goto cap_err;
|
||||
sdram_detect_bank(cap_info, coltmp, bktmp);
|
||||
sdram_detect_dbw(cap_info, dram_type);
|
||||
} else {
|
||||
/* detect bg for ddr4 */
|
||||
coltmp = 10;
|
||||
bktmp = 4;
|
||||
rowtmp = 17;
|
||||
|
||||
col = 10;
|
||||
bk = 2;
|
||||
cap_info->col = col;
|
||||
cap_info->bk = bk;
|
||||
sdram_detect_bg(cap_info, coltmp);
|
||||
}
|
||||
|
||||
/* detect row */
|
||||
if (sdram_detect_row(cap_info, coltmp, bktmp, rowtmp) != 0)
|
||||
goto cap_err;
|
||||
|
||||
/* detect row_3_4 */
|
||||
sdram_detect_row_3_4(cap_info, coltmp, bktmp);
|
||||
|
||||
/* bw and cs detect using data training */
|
||||
if (data_training(dram, 1, dram_type) == 0)
|
||||
cs = 1;
|
||||
else
|
||||
cs = 0;
|
||||
cap_info->rank = cs + 1;
|
||||
|
||||
bw = 2;
|
||||
cap_info->bw = bw;
|
||||
|
||||
cap_info->cs0_high16bit_row = cap_info->cs0_row;
|
||||
if (cs) {
|
||||
cap_info->cs1_row = cap_info->cs0_row;
|
||||
cap_info->cs1_high16bit_row = cap_info->cs0_row;
|
||||
} else {
|
||||
cap_info->cs1_row = 0;
|
||||
cap_info->cs1_high16bit_row = 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
cap_err:
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int sdram_init_detect(struct dram_info *dram,
|
||||
struct rk3328_sdram_params *sdram_params)
|
||||
{
|
||||
u32 sys_reg = 0;
|
||||
u32 sys_reg3 = 0;
|
||||
struct sdram_cap_info *cap_info = &sdram_params->ch.cap_info;
|
||||
|
||||
debug("Starting SDRAM initialization...\n");
|
||||
|
||||
memcpy(&sdram_ch, &sdram_params->ch,
|
||||
sizeof(struct rk3328_sdram_channel));
|
||||
|
||||
sdram_init(dram, sdram_params, 1);
|
||||
dram_detect_cap(dram, sdram_params, 0);
|
||||
|
||||
/* modify bw, cs related timing */
|
||||
pctl_remodify_sdram_params(&sdram_params->pctl_regs, cap_info,
|
||||
sdram_params->base.dramtype);
|
||||
|
||||
if (cap_info->bw == 2)
|
||||
sdram_ch.noc_timings.ddrtiming.b.bwratio = 0;
|
||||
else
|
||||
sdram_ch.noc_timings.ddrtiming.b.bwratio = 1;
|
||||
|
||||
/* reinit sdram by real dram cap */
|
||||
sdram_init(dram, sdram_params, 0);
|
||||
|
||||
/* redetect cs1 row */
|
||||
sdram_detect_cs1_row(cap_info, sdram_params->base.dramtype);
|
||||
if (cap_info->cs1_row) {
|
||||
sys_reg = readl(&dram->grf->os_reg[2]);
|
||||
sys_reg3 = readl(&dram->grf->os_reg[3]);
|
||||
SYS_REG_ENC_CS1_ROW(cap_info->cs1_row,
|
||||
sys_reg, sys_reg3, 0);
|
||||
writel(sys_reg, &dram->grf->os_reg[2]);
|
||||
writel(sys_reg3, &dram->grf->os_reg[3]);
|
||||
}
|
||||
|
||||
sdram_print_ddr_info(&sdram_params->ch.cap_info, &sdram_params->base);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rk3328_dmc_init(struct udevice *dev)
|
||||
{
|
||||
struct dram_info *priv = dev_get_priv(dev);
|
||||
struct rockchip_dmc_plat *plat = dev_get_platdata(dev);
|
||||
int ret;
|
||||
|
||||
#if !CONFIG_IS_ENABLED(OF_PLATDATA)
|
||||
struct rk3328_sdram_params *params = &plat->sdram_params;
|
||||
#else
|
||||
struct dtd_rockchip_rk3328_dmc *dtplat = &plat->dtplat;
|
||||
struct rk3328_sdram_params *params =
|
||||
(void *)dtplat->rockchip_sdram_params;
|
||||
|
||||
ret = conv_of_platdata(dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
#endif
|
||||
priv->phy = regmap_get_range(plat->map, 0);
|
||||
priv->pctl = regmap_get_range(plat->map, 1);
|
||||
priv->grf = regmap_get_range(plat->map, 2);
|
||||
priv->cru = regmap_get_range(plat->map, 3);
|
||||
priv->msch = regmap_get_range(plat->map, 4);
|
||||
priv->ddr_grf = regmap_get_range(plat->map, 5);
|
||||
|
||||
debug("%s phy %p pctrl %p grf %p cru %p msch %p ddr_grf %p\n",
|
||||
__func__, priv->phy, priv->pctl, priv->grf, priv->cru,
|
||||
priv->msch, priv->ddr_grf);
|
||||
ret = sdram_init_detect(priv, params);
|
||||
if (ret < 0) {
|
||||
printf("%s DRAM init failed%d\n", __func__, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rk3328_dmc_ofdata_to_platdata(struct udevice *dev)
|
||||
{
|
||||
#if !CONFIG_IS_ENABLED(OF_PLATDATA)
|
||||
struct rockchip_dmc_plat *plat = dev_get_platdata(dev);
|
||||
int ret;
|
||||
|
||||
ret = dev_read_u32_array(dev, "rockchip,sdram-params",
|
||||
(u32 *)&plat->sdram_params,
|
||||
sizeof(plat->sdram_params) / sizeof(u32));
|
||||
if (ret) {
|
||||
printf("%s: Cannot read rockchip,sdram-params %d\n",
|
||||
__func__, ret);
|
||||
return ret;
|
||||
}
|
||||
ret = regmap_init_mem(dev, &plat->map);
|
||||
if (ret)
|
||||
printf("%s: regmap failed %d\n", __func__, ret);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static int rk3328_dmc_probe(struct udevice *dev)
|
||||
{
|
||||
#ifdef CONFIG_TPL_BUILD
|
||||
if (rk3328_dmc_init(dev))
|
||||
return 0;
|
||||
#else
|
||||
struct dram_info *priv = dev_get_priv(dev);
|
||||
|
||||
priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
|
||||
debug("%s: grf=%p\n", __func__, priv->grf);
|
||||
priv->info.base = CONFIG_SYS_SDRAM_BASE;
|
||||
priv->info.size = rockchip_sdram_size(
|
||||
(phys_addr_t)&priv->grf->os_reg[2]);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rk3328_dmc_get_info(struct udevice *dev, struct ram_info *info)
|
||||
{
|
||||
struct dram_info *priv = dev_get_priv(dev);
|
||||
|
||||
*info = priv->info;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct ram_ops rk3328_dmc_ops = {
|
||||
.get_info = rk3328_dmc_get_info,
|
||||
};
|
||||
|
||||
static const struct udevice_id rk3328_dmc_ids[] = {
|
||||
{ .compatible = "rockchip,rk3328-dmc" },
|
||||
{ }
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(dmc_rk3328) = {
|
||||
.name = "rockchip_rk3328_dmc",
|
||||
.id = UCLASS_RAM,
|
||||
.of_match = rk3328_dmc_ids,
|
||||
.ops = &rk3328_dmc_ops,
|
||||
#ifdef CONFIG_TPL_BUILD
|
||||
.ofdata_to_platdata = rk3328_dmc_ofdata_to_platdata,
|
||||
#endif
|
||||
.probe = rk3328_dmc_probe,
|
||||
.priv_auto_alloc_size = sizeof(struct dram_info),
|
||||
#ifdef CONFIG_TPL_BUILD
|
||||
.platdata_auto_alloc_size = sizeof(struct rockchip_dmc_plat),
|
||||
#endif
|
||||
};
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,37 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright (c) 2015 Google, Inc
|
||||
* Written by Simon Glass <sjg@chromium.org>
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <errno.h>
|
||||
#include <ram.h>
|
||||
#include <asm/test.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
static int sandbox_get_info(struct udevice *dev, struct ram_info *info)
|
||||
{
|
||||
info->base = 0;
|
||||
info->size = gd->ram_size;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct ram_ops sandbox_ram_ops = {
|
||||
.get_info = sandbox_get_info,
|
||||
};
|
||||
|
||||
static const struct udevice_id sandbox_ram_ids[] = {
|
||||
{ .compatible = "sandbox,ram" },
|
||||
{ }
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(warm_ram_sandbox) = {
|
||||
.name = "ram_sandbox",
|
||||
.id = UCLASS_RAM,
|
||||
.of_match = sandbox_ram_ids,
|
||||
.ops = &sandbox_ram_ops,
|
||||
};
|
||||
@@ -0,0 +1,408 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright (C) 2017, STMicroelectronics - All Rights Reserved
|
||||
* Author(s): Vikas Manocha, <vikas.manocha@st.com> for STMicroelectronics.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <clk.h>
|
||||
#include <dm.h>
|
||||
#include <ram.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
#define MEM_MODE_MASK GENMASK(2, 0)
|
||||
#define SWP_FMC_OFFSET 10
|
||||
#define SWP_FMC_MASK GENMASK(SWP_FMC_OFFSET+1, SWP_FMC_OFFSET)
|
||||
#define NOT_FOUND 0xff
|
||||
|
||||
struct stm32_fmc_regs {
|
||||
/* 0x0 */
|
||||
u32 bcr1; /* NOR/PSRAM Chip select control register 1 */
|
||||
u32 btr1; /* SRAM/NOR-Flash Chip select timing register 1 */
|
||||
u32 bcr2; /* NOR/PSRAM Chip select Control register 2 */
|
||||
u32 btr2; /* SRAM/NOR-Flash Chip select timing register 2 */
|
||||
u32 bcr3; /* NOR/PSRAMChip select Control register 3 */
|
||||
u32 btr3; /* SRAM/NOR-Flash Chip select timing register 3 */
|
||||
u32 bcr4; /* NOR/PSRAM Chip select Control register 4 */
|
||||
u32 btr4; /* SRAM/NOR-Flash Chip select timing register 4 */
|
||||
u32 reserved1[24];
|
||||
|
||||
/* 0x80 */
|
||||
u32 pcr; /* NAND Flash control register */
|
||||
u32 sr; /* FIFO status and interrupt register */
|
||||
u32 pmem; /* Common memory space timing register */
|
||||
u32 patt; /* Attribute memory space timing registers */
|
||||
u32 reserved2[1];
|
||||
u32 eccr; /* ECC result registers */
|
||||
u32 reserved3[27];
|
||||
|
||||
/* 0x104 */
|
||||
u32 bwtr1; /* SRAM/NOR-Flash write timing register 1 */
|
||||
u32 reserved4[1];
|
||||
u32 bwtr2; /* SRAM/NOR-Flash write timing register 2 */
|
||||
u32 reserved5[1];
|
||||
u32 bwtr3; /* SRAM/NOR-Flash write timing register 3 */
|
||||
u32 reserved6[1];
|
||||
u32 bwtr4; /* SRAM/NOR-Flash write timing register 4 */
|
||||
u32 reserved7[8];
|
||||
|
||||
/* 0x140 */
|
||||
u32 sdcr1; /* SDRAM Control register 1 */
|
||||
u32 sdcr2; /* SDRAM Control register 2 */
|
||||
u32 sdtr1; /* SDRAM Timing register 1 */
|
||||
u32 sdtr2; /* SDRAM Timing register 2 */
|
||||
u32 sdcmr; /* SDRAM Mode register */
|
||||
u32 sdrtr; /* SDRAM Refresh timing register */
|
||||
u32 sdsr; /* SDRAM Status register */
|
||||
};
|
||||
|
||||
/*
|
||||
* NOR/PSRAM Control register BCR1
|
||||
* FMC controller Enable, only availabe for H7
|
||||
*/
|
||||
#define FMC_BCR1_FMCEN BIT(31)
|
||||
|
||||
/* Control register SDCR */
|
||||
#define FMC_SDCR_RPIPE_SHIFT 13 /* RPIPE bit shift */
|
||||
#define FMC_SDCR_RBURST_SHIFT 12 /* RBURST bit shift */
|
||||
#define FMC_SDCR_SDCLK_SHIFT 10 /* SDRAM clock divisor shift */
|
||||
#define FMC_SDCR_WP_SHIFT 9 /* Write protection shift */
|
||||
#define FMC_SDCR_CAS_SHIFT 7 /* CAS latency shift */
|
||||
#define FMC_SDCR_NB_SHIFT 6 /* Number of banks shift */
|
||||
#define FMC_SDCR_MWID_SHIFT 4 /* Memory width shift */
|
||||
#define FMC_SDCR_NR_SHIFT 2 /* Number of row address bits shift */
|
||||
#define FMC_SDCR_NC_SHIFT 0 /* Number of col address bits shift */
|
||||
|
||||
/* Timings register SDTR */
|
||||
#define FMC_SDTR_TMRD_SHIFT 0 /* Load mode register to active */
|
||||
#define FMC_SDTR_TXSR_SHIFT 4 /* Exit self-refresh time */
|
||||
#define FMC_SDTR_TRAS_SHIFT 8 /* Self-refresh time */
|
||||
#define FMC_SDTR_TRC_SHIFT 12 /* Row cycle delay */
|
||||
#define FMC_SDTR_TWR_SHIFT 16 /* Recovery delay */
|
||||
#define FMC_SDTR_TRP_SHIFT 20 /* Row precharge delay */
|
||||
#define FMC_SDTR_TRCD_SHIFT 24 /* Row-to-column delay */
|
||||
|
||||
#define FMC_SDCMR_NRFS_SHIFT 5
|
||||
|
||||
#define FMC_SDCMR_MODE_NORMAL 0
|
||||
#define FMC_SDCMR_MODE_START_CLOCK 1
|
||||
#define FMC_SDCMR_MODE_PRECHARGE 2
|
||||
#define FMC_SDCMR_MODE_AUTOREFRESH 3
|
||||
#define FMC_SDCMR_MODE_WRITE_MODE 4
|
||||
#define FMC_SDCMR_MODE_SELFREFRESH 5
|
||||
#define FMC_SDCMR_MODE_POWERDOWN 6
|
||||
|
||||
#define FMC_SDCMR_BANK_1 BIT(4)
|
||||
#define FMC_SDCMR_BANK_2 BIT(3)
|
||||
|
||||
#define FMC_SDCMR_MODE_REGISTER_SHIFT 9
|
||||
|
||||
#define FMC_SDSR_BUSY BIT(5)
|
||||
|
||||
#define FMC_BUSY_WAIT(regs) do { \
|
||||
__asm__ __volatile__ ("dsb" : : : "memory"); \
|
||||
while (regs->sdsr & FMC_SDSR_BUSY) \
|
||||
; \
|
||||
} while (0)
|
||||
|
||||
struct stm32_sdram_control {
|
||||
u8 no_columns;
|
||||
u8 no_rows;
|
||||
u8 memory_width;
|
||||
u8 no_banks;
|
||||
u8 cas_latency;
|
||||
u8 sdclk;
|
||||
u8 rd_burst;
|
||||
u8 rd_pipe_delay;
|
||||
};
|
||||
|
||||
struct stm32_sdram_timing {
|
||||
u8 tmrd;
|
||||
u8 txsr;
|
||||
u8 tras;
|
||||
u8 trc;
|
||||
u8 trp;
|
||||
u8 twr;
|
||||
u8 trcd;
|
||||
};
|
||||
enum stm32_fmc_bank {
|
||||
SDRAM_BANK1,
|
||||
SDRAM_BANK2,
|
||||
MAX_SDRAM_BANK,
|
||||
};
|
||||
|
||||
enum stm32_fmc_family {
|
||||
STM32F7_FMC,
|
||||
STM32H7_FMC,
|
||||
};
|
||||
|
||||
struct bank_params {
|
||||
struct stm32_sdram_control *sdram_control;
|
||||
struct stm32_sdram_timing *sdram_timing;
|
||||
u32 sdram_ref_count;
|
||||
enum stm32_fmc_bank target_bank;
|
||||
};
|
||||
|
||||
struct stm32_sdram_params {
|
||||
struct stm32_fmc_regs *base;
|
||||
u8 no_sdram_banks;
|
||||
struct bank_params bank_params[MAX_SDRAM_BANK];
|
||||
enum stm32_fmc_family family;
|
||||
};
|
||||
|
||||
#define SDRAM_MODE_BL_SHIFT 0
|
||||
#define SDRAM_MODE_CAS_SHIFT 4
|
||||
#define SDRAM_MODE_BL 0
|
||||
|
||||
int stm32_sdram_init(struct udevice *dev)
|
||||
{
|
||||
struct stm32_sdram_params *params = dev_get_platdata(dev);
|
||||
struct stm32_sdram_control *control;
|
||||
struct stm32_sdram_timing *timing;
|
||||
struct stm32_fmc_regs *regs = params->base;
|
||||
enum stm32_fmc_bank target_bank;
|
||||
u32 ctb; /* SDCMR register: Command Target Bank */
|
||||
u32 ref_count;
|
||||
u8 i;
|
||||
|
||||
/* disable the FMC controller */
|
||||
if (params->family == STM32H7_FMC)
|
||||
clrbits_le32(®s->bcr1, FMC_BCR1_FMCEN);
|
||||
|
||||
for (i = 0; i < params->no_sdram_banks; i++) {
|
||||
control = params->bank_params[i].sdram_control;
|
||||
timing = params->bank_params[i].sdram_timing;
|
||||
target_bank = params->bank_params[i].target_bank;
|
||||
ref_count = params->bank_params[i].sdram_ref_count;
|
||||
|
||||
writel(control->sdclk << FMC_SDCR_SDCLK_SHIFT
|
||||
| control->cas_latency << FMC_SDCR_CAS_SHIFT
|
||||
| control->no_banks << FMC_SDCR_NB_SHIFT
|
||||
| control->memory_width << FMC_SDCR_MWID_SHIFT
|
||||
| control->no_rows << FMC_SDCR_NR_SHIFT
|
||||
| control->no_columns << FMC_SDCR_NC_SHIFT
|
||||
| control->rd_pipe_delay << FMC_SDCR_RPIPE_SHIFT
|
||||
| control->rd_burst << FMC_SDCR_RBURST_SHIFT,
|
||||
®s->sdcr1);
|
||||
|
||||
if (target_bank == SDRAM_BANK2)
|
||||
writel(control->cas_latency << FMC_SDCR_CAS_SHIFT
|
||||
| control->no_banks << FMC_SDCR_NB_SHIFT
|
||||
| control->memory_width << FMC_SDCR_MWID_SHIFT
|
||||
| control->no_rows << FMC_SDCR_NR_SHIFT
|
||||
| control->no_columns << FMC_SDCR_NC_SHIFT,
|
||||
®s->sdcr2);
|
||||
|
||||
writel(timing->trcd << FMC_SDTR_TRCD_SHIFT
|
||||
| timing->trp << FMC_SDTR_TRP_SHIFT
|
||||
| timing->twr << FMC_SDTR_TWR_SHIFT
|
||||
| timing->trc << FMC_SDTR_TRC_SHIFT
|
||||
| timing->tras << FMC_SDTR_TRAS_SHIFT
|
||||
| timing->txsr << FMC_SDTR_TXSR_SHIFT
|
||||
| timing->tmrd << FMC_SDTR_TMRD_SHIFT,
|
||||
®s->sdtr1);
|
||||
|
||||
if (target_bank == SDRAM_BANK2)
|
||||
writel(timing->trcd << FMC_SDTR_TRCD_SHIFT
|
||||
| timing->trp << FMC_SDTR_TRP_SHIFT
|
||||
| timing->twr << FMC_SDTR_TWR_SHIFT
|
||||
| timing->trc << FMC_SDTR_TRC_SHIFT
|
||||
| timing->tras << FMC_SDTR_TRAS_SHIFT
|
||||
| timing->txsr << FMC_SDTR_TXSR_SHIFT
|
||||
| timing->tmrd << FMC_SDTR_TMRD_SHIFT,
|
||||
®s->sdtr2);
|
||||
|
||||
if (target_bank == SDRAM_BANK1)
|
||||
ctb = FMC_SDCMR_BANK_1;
|
||||
else
|
||||
ctb = FMC_SDCMR_BANK_2;
|
||||
|
||||
writel(ctb | FMC_SDCMR_MODE_START_CLOCK, ®s->sdcmr);
|
||||
udelay(200); /* 200 us delay, page 10, "Power-Up" */
|
||||
FMC_BUSY_WAIT(regs);
|
||||
|
||||
writel(ctb | FMC_SDCMR_MODE_PRECHARGE, ®s->sdcmr);
|
||||
udelay(100);
|
||||
FMC_BUSY_WAIT(regs);
|
||||
|
||||
writel((ctb | FMC_SDCMR_MODE_AUTOREFRESH | 7 << FMC_SDCMR_NRFS_SHIFT),
|
||||
®s->sdcmr);
|
||||
udelay(100);
|
||||
FMC_BUSY_WAIT(regs);
|
||||
|
||||
writel(ctb | (SDRAM_MODE_BL << SDRAM_MODE_BL_SHIFT
|
||||
| control->cas_latency << SDRAM_MODE_CAS_SHIFT)
|
||||
<< FMC_SDCMR_MODE_REGISTER_SHIFT | FMC_SDCMR_MODE_WRITE_MODE,
|
||||
®s->sdcmr);
|
||||
udelay(100);
|
||||
FMC_BUSY_WAIT(regs);
|
||||
|
||||
writel(ctb | FMC_SDCMR_MODE_NORMAL, ®s->sdcmr);
|
||||
FMC_BUSY_WAIT(regs);
|
||||
|
||||
/* Refresh timer */
|
||||
writel(ref_count << 1, ®s->sdrtr);
|
||||
}
|
||||
|
||||
/* enable the FMC controller */
|
||||
if (params->family == STM32H7_FMC)
|
||||
setbits_le32(®s->bcr1, FMC_BCR1_FMCEN);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int stm32_fmc_ofdata_to_platdata(struct udevice *dev)
|
||||
{
|
||||
struct stm32_sdram_params *params = dev_get_platdata(dev);
|
||||
struct bank_params *bank_params;
|
||||
struct ofnode_phandle_args args;
|
||||
u32 *syscfg_base;
|
||||
u32 mem_remap;
|
||||
u32 swp_fmc;
|
||||
ofnode bank_node;
|
||||
char *bank_name;
|
||||
u8 bank = 0;
|
||||
int ret;
|
||||
|
||||
ret = dev_read_phandle_with_args(dev, "st,syscfg", NULL, 0, 0,
|
||||
&args);
|
||||
if (ret) {
|
||||
dev_dbg(dev, "%s: can't find syscon device (%d)\n", __func__, ret);
|
||||
} else {
|
||||
syscfg_base = (u32 *)ofnode_get_addr(args.node);
|
||||
|
||||
mem_remap = dev_read_u32_default(dev, "st,mem_remap", NOT_FOUND);
|
||||
if (mem_remap != NOT_FOUND) {
|
||||
/* set memory mapping selection */
|
||||
clrsetbits_le32(syscfg_base, MEM_MODE_MASK, mem_remap);
|
||||
} else {
|
||||
dev_dbg(dev, "%s: cannot find st,mem_remap property\n", __func__);
|
||||
}
|
||||
|
||||
swp_fmc = dev_read_u32_default(dev, "st,swp_fmc", NOT_FOUND);
|
||||
if (swp_fmc != NOT_FOUND) {
|
||||
/* set fmc swapping selection */
|
||||
clrsetbits_le32(syscfg_base, SWP_FMC_MASK, swp_fmc << SWP_FMC_OFFSET);
|
||||
} else {
|
||||
dev_dbg(dev, "%s: cannot find st,swp_fmc property\n", __func__);
|
||||
}
|
||||
|
||||
dev_dbg(dev, "syscfg %x = %x\n", (u32)syscfg_base, *syscfg_base);
|
||||
}
|
||||
|
||||
dev_for_each_subnode(bank_node, dev) {
|
||||
/* extract the bank index from DT */
|
||||
bank_name = (char *)ofnode_get_name(bank_node);
|
||||
strsep(&bank_name, "@");
|
||||
if (!bank_name) {
|
||||
pr_err("missing sdram bank index");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
bank_params = ¶ms->bank_params[bank];
|
||||
strict_strtoul(bank_name, 10,
|
||||
(long unsigned int *)&bank_params->target_bank);
|
||||
|
||||
if (bank_params->target_bank >= MAX_SDRAM_BANK) {
|
||||
pr_err("Found bank %d , but only bank 0 and 1 are supported",
|
||||
bank_params->target_bank);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
debug("Find bank %s %u\n", bank_name, bank_params->target_bank);
|
||||
|
||||
params->bank_params[bank].sdram_control =
|
||||
(struct stm32_sdram_control *)
|
||||
ofnode_read_u8_array_ptr(bank_node,
|
||||
"st,sdram-control",
|
||||
sizeof(struct stm32_sdram_control));
|
||||
|
||||
if (!params->bank_params[bank].sdram_control) {
|
||||
pr_err("st,sdram-control not found for %s",
|
||||
ofnode_get_name(bank_node));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
||||
params->bank_params[bank].sdram_timing =
|
||||
(struct stm32_sdram_timing *)
|
||||
ofnode_read_u8_array_ptr(bank_node,
|
||||
"st,sdram-timing",
|
||||
sizeof(struct stm32_sdram_timing));
|
||||
|
||||
if (!params->bank_params[bank].sdram_timing) {
|
||||
pr_err("st,sdram-timing not found for %s",
|
||||
ofnode_get_name(bank_node));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
||||
bank_params->sdram_ref_count = ofnode_read_u32_default(bank_node,
|
||||
"st,sdram-refcount", 8196);
|
||||
bank++;
|
||||
}
|
||||
|
||||
params->no_sdram_banks = bank;
|
||||
debug("%s, no of banks = %d\n", __func__, params->no_sdram_banks);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int stm32_fmc_probe(struct udevice *dev)
|
||||
{
|
||||
struct stm32_sdram_params *params = dev_get_platdata(dev);
|
||||
int ret;
|
||||
fdt_addr_t addr;
|
||||
|
||||
addr = dev_read_addr(dev);
|
||||
if (addr == FDT_ADDR_T_NONE)
|
||||
return -EINVAL;
|
||||
|
||||
params->base = (struct stm32_fmc_regs *)addr;
|
||||
params->family = dev_get_driver_data(dev);
|
||||
|
||||
#ifdef CONFIG_CLK
|
||||
struct clk clk;
|
||||
|
||||
ret = clk_get_by_index(dev, 0, &clk);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = clk_enable(&clk);
|
||||
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to enable clock\n");
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
ret = stm32_sdram_init(dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int stm32_fmc_get_info(struct udevice *dev, struct ram_info *info)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct ram_ops stm32_fmc_ops = {
|
||||
.get_info = stm32_fmc_get_info,
|
||||
};
|
||||
|
||||
static const struct udevice_id stm32_fmc_ids[] = {
|
||||
{ .compatible = "st,stm32-fmc", .data = STM32F7_FMC },
|
||||
{ .compatible = "st,stm32h7-fmc", .data = STM32H7_FMC },
|
||||
{ }
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(stm32_fmc) = {
|
||||
.name = "stm32_fmc",
|
||||
.id = UCLASS_RAM,
|
||||
.of_match = stm32_fmc_ids,
|
||||
.ops = &stm32_fmc_ops,
|
||||
.ofdata_to_platdata = stm32_fmc_ofdata_to_platdata,
|
||||
.probe = stm32_fmc_probe,
|
||||
.platdata_auto_alloc_size = sizeof(struct stm32_sdram_params),
|
||||
};
|
||||
@@ -0,0 +1,49 @@
|
||||
|
||||
config STM32MP1_DDR
|
||||
bool "STM32MP1 DDR driver"
|
||||
depends on DM && OF_CONTROL && ARCH_STM32MP
|
||||
select RAM
|
||||
select SPL_RAM if SPL
|
||||
default y
|
||||
help
|
||||
activate STM32MP1 DDR controller driver for STM32MP1 soc
|
||||
family: support for LPDDR2, LPDDR3 and DDR3
|
||||
the SDRAM parameters for controleur and phy need to be provided
|
||||
in device tree (computed by DDR tuning tools)
|
||||
|
||||
config STM32MP1_DDR_INTERACTIVE
|
||||
bool "STM32MP1 DDR driver : interactive support"
|
||||
depends on STM32MP1_DDR
|
||||
help
|
||||
activate interactive support in STM32MP1 DDR controller driver
|
||||
used for DDR tuning tools
|
||||
to enter in intercative mode type 'd' during SPL DDR driver
|
||||
initialisation
|
||||
|
||||
config STM32MP1_DDR_INTERACTIVE_FORCE
|
||||
bool "STM32MP1 DDR driver : force interactive mode"
|
||||
depends on STM32MP1_DDR_INTERACTIVE
|
||||
default n
|
||||
help
|
||||
force interactive mode in STM32MP1 DDR controller driver
|
||||
skip the polling of character 'd' in console
|
||||
useful when SPL is loaded in sysram
|
||||
directly by programmer
|
||||
|
||||
config STM32MP1_DDR_TESTS
|
||||
bool "STM32MP1 DDR driver : tests support"
|
||||
depends on STM32MP1_DDR_INTERACTIVE
|
||||
default y
|
||||
help
|
||||
activate test support for interactive support in
|
||||
STM32MP1 DDR controller driver: command test
|
||||
|
||||
config STM32MP1_DDR_TUNING
|
||||
bool "STM32MP1 DDR driver : support of tuning"
|
||||
depends on STM32MP1_DDR_INTERACTIVE
|
||||
default y
|
||||
help
|
||||
activate tuning command in STM32MP1 DDR interactive mode
|
||||
used for DDR tuning tools
|
||||
- DQ Deskew algorithm
|
||||
- DQS Trimming
|
||||
@@ -0,0 +1,15 @@
|
||||
# SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
|
||||
#
|
||||
# Copyright (C) 2018, STMicroelectronics - All Rights Reserved
|
||||
#
|
||||
|
||||
obj-y += stm32mp1_ram.o
|
||||
obj-y += stm32mp1_ddr.o
|
||||
|
||||
obj-$(CONFIG_STM32MP1_DDR_INTERACTIVE) += stm32mp1_interactive.o
|
||||
obj-$(CONFIG_STM32MP1_DDR_TESTS) += stm32mp1_tests.o
|
||||
obj-$(CONFIG_STM32MP1_DDR_TUNING) += stm32mp1_tuning.o
|
||||
|
||||
ifneq ($(DDR_INTERACTIVE),)
|
||||
CFLAGS_stm32mp1_interactive.o += -DCONFIG_STM32MP1_DDR_INTERACTIVE_FORCE=y
|
||||
endif
|
||||
@@ -0,0 +1,813 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
|
||||
/*
|
||||
* Copyright (C) 2018, STMicroelectronics - All Rights Reserved
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <clk.h>
|
||||
#include <ram.h>
|
||||
#include <reset.h>
|
||||
#include <timer.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/arch/ddr.h>
|
||||
#include <linux/iopoll.h>
|
||||
#include "stm32mp1_ddr.h"
|
||||
#include "stm32mp1_ddr_regs.h"
|
||||
|
||||
#define RCC_DDRITFCR 0xD8
|
||||
|
||||
#define RCC_DDRITFCR_DDRCAPBRST (BIT(14))
|
||||
#define RCC_DDRITFCR_DDRCAXIRST (BIT(15))
|
||||
#define RCC_DDRITFCR_DDRCORERST (BIT(16))
|
||||
#define RCC_DDRITFCR_DPHYAPBRST (BIT(17))
|
||||
#define RCC_DDRITFCR_DPHYRST (BIT(18))
|
||||
#define RCC_DDRITFCR_DPHYCTLRST (BIT(19))
|
||||
|
||||
struct reg_desc {
|
||||
const char *name;
|
||||
u16 offset; /* offset for base address */
|
||||
u8 par_offset; /* offset for parameter array */
|
||||
};
|
||||
|
||||
#define INVALID_OFFSET 0xFF
|
||||
|
||||
#define DDRCTL_REG(x, y) \
|
||||
{#x,\
|
||||
offsetof(struct stm32mp1_ddrctl, x),\
|
||||
offsetof(struct y, x)}
|
||||
|
||||
#define DDRPHY_REG(x, y) \
|
||||
{#x,\
|
||||
offsetof(struct stm32mp1_ddrphy, x),\
|
||||
offsetof(struct y, x)}
|
||||
|
||||
#define DDR_REG_DYN(x) \
|
||||
{#x,\
|
||||
offsetof(struct stm32mp1_ddrctl, x),\
|
||||
INVALID_OFFSET}
|
||||
|
||||
#define DDRPHY_REG_DYN(x) \
|
||||
{#x,\
|
||||
offsetof(struct stm32mp1_ddrphy, x),\
|
||||
INVALID_OFFSET}
|
||||
|
||||
/***********************************************************
|
||||
* PARAMETERS: value get from device tree :
|
||||
* size / order need to be aligned with binding
|
||||
* modification NOT ALLOWED !!!
|
||||
***********************************************************/
|
||||
#define DDRCTL_REG_REG_SIZE 25 /* st,ctl-reg */
|
||||
#define DDRCTL_REG_TIMING_SIZE 12 /* st,ctl-timing */
|
||||
#define DDRCTL_REG_MAP_SIZE 9 /* st,ctl-map */
|
||||
#define DDRCTL_REG_PERF_SIZE 17 /* st,ctl-perf */
|
||||
|
||||
#define DDRPHY_REG_REG_SIZE 11 /* st,phy-reg */
|
||||
#define DDRPHY_REG_TIMING_SIZE 10 /* st,phy-timing */
|
||||
#define DDRPHY_REG_CAL_SIZE 12 /* st,phy-cal */
|
||||
|
||||
#define DDRCTL_REG_REG(x) DDRCTL_REG(x, stm32mp1_ddrctrl_reg)
|
||||
static const struct reg_desc ddr_reg[DDRCTL_REG_REG_SIZE] = {
|
||||
DDRCTL_REG_REG(mstr),
|
||||
DDRCTL_REG_REG(mrctrl0),
|
||||
DDRCTL_REG_REG(mrctrl1),
|
||||
DDRCTL_REG_REG(derateen),
|
||||
DDRCTL_REG_REG(derateint),
|
||||
DDRCTL_REG_REG(pwrctl),
|
||||
DDRCTL_REG_REG(pwrtmg),
|
||||
DDRCTL_REG_REG(hwlpctl),
|
||||
DDRCTL_REG_REG(rfshctl0),
|
||||
DDRCTL_REG_REG(rfshctl3),
|
||||
DDRCTL_REG_REG(crcparctl0),
|
||||
DDRCTL_REG_REG(zqctl0),
|
||||
DDRCTL_REG_REG(dfitmg0),
|
||||
DDRCTL_REG_REG(dfitmg1),
|
||||
DDRCTL_REG_REG(dfilpcfg0),
|
||||
DDRCTL_REG_REG(dfiupd0),
|
||||
DDRCTL_REG_REG(dfiupd1),
|
||||
DDRCTL_REG_REG(dfiupd2),
|
||||
DDRCTL_REG_REG(dfiphymstr),
|
||||
DDRCTL_REG_REG(odtmap),
|
||||
DDRCTL_REG_REG(dbg0),
|
||||
DDRCTL_REG_REG(dbg1),
|
||||
DDRCTL_REG_REG(dbgcmd),
|
||||
DDRCTL_REG_REG(poisoncfg),
|
||||
DDRCTL_REG_REG(pccfg),
|
||||
};
|
||||
|
||||
#define DDRCTL_REG_TIMING(x) DDRCTL_REG(x, stm32mp1_ddrctrl_timing)
|
||||
static const struct reg_desc ddr_timing[DDRCTL_REG_TIMING_SIZE] = {
|
||||
DDRCTL_REG_TIMING(rfshtmg),
|
||||
DDRCTL_REG_TIMING(dramtmg0),
|
||||
DDRCTL_REG_TIMING(dramtmg1),
|
||||
DDRCTL_REG_TIMING(dramtmg2),
|
||||
DDRCTL_REG_TIMING(dramtmg3),
|
||||
DDRCTL_REG_TIMING(dramtmg4),
|
||||
DDRCTL_REG_TIMING(dramtmg5),
|
||||
DDRCTL_REG_TIMING(dramtmg6),
|
||||
DDRCTL_REG_TIMING(dramtmg7),
|
||||
DDRCTL_REG_TIMING(dramtmg8),
|
||||
DDRCTL_REG_TIMING(dramtmg14),
|
||||
DDRCTL_REG_TIMING(odtcfg),
|
||||
};
|
||||
|
||||
#define DDRCTL_REG_MAP(x) DDRCTL_REG(x, stm32mp1_ddrctrl_map)
|
||||
static const struct reg_desc ddr_map[DDRCTL_REG_MAP_SIZE] = {
|
||||
DDRCTL_REG_MAP(addrmap1),
|
||||
DDRCTL_REG_MAP(addrmap2),
|
||||
DDRCTL_REG_MAP(addrmap3),
|
||||
DDRCTL_REG_MAP(addrmap4),
|
||||
DDRCTL_REG_MAP(addrmap5),
|
||||
DDRCTL_REG_MAP(addrmap6),
|
||||
DDRCTL_REG_MAP(addrmap9),
|
||||
DDRCTL_REG_MAP(addrmap10),
|
||||
DDRCTL_REG_MAP(addrmap11),
|
||||
};
|
||||
|
||||
#define DDRCTL_REG_PERF(x) DDRCTL_REG(x, stm32mp1_ddrctrl_perf)
|
||||
static const struct reg_desc ddr_perf[DDRCTL_REG_PERF_SIZE] = {
|
||||
DDRCTL_REG_PERF(sched),
|
||||
DDRCTL_REG_PERF(sched1),
|
||||
DDRCTL_REG_PERF(perfhpr1),
|
||||
DDRCTL_REG_PERF(perflpr1),
|
||||
DDRCTL_REG_PERF(perfwr1),
|
||||
DDRCTL_REG_PERF(pcfgr_0),
|
||||
DDRCTL_REG_PERF(pcfgw_0),
|
||||
DDRCTL_REG_PERF(pcfgqos0_0),
|
||||
DDRCTL_REG_PERF(pcfgqos1_0),
|
||||
DDRCTL_REG_PERF(pcfgwqos0_0),
|
||||
DDRCTL_REG_PERF(pcfgwqos1_0),
|
||||
DDRCTL_REG_PERF(pcfgr_1),
|
||||
DDRCTL_REG_PERF(pcfgw_1),
|
||||
DDRCTL_REG_PERF(pcfgqos0_1),
|
||||
DDRCTL_REG_PERF(pcfgqos1_1),
|
||||
DDRCTL_REG_PERF(pcfgwqos0_1),
|
||||
DDRCTL_REG_PERF(pcfgwqos1_1),
|
||||
};
|
||||
|
||||
#define DDRPHY_REG_REG(x) DDRPHY_REG(x, stm32mp1_ddrphy_reg)
|
||||
static const struct reg_desc ddrphy_reg[DDRPHY_REG_REG_SIZE] = {
|
||||
DDRPHY_REG_REG(pgcr),
|
||||
DDRPHY_REG_REG(aciocr),
|
||||
DDRPHY_REG_REG(dxccr),
|
||||
DDRPHY_REG_REG(dsgcr),
|
||||
DDRPHY_REG_REG(dcr),
|
||||
DDRPHY_REG_REG(odtcr),
|
||||
DDRPHY_REG_REG(zq0cr1),
|
||||
DDRPHY_REG_REG(dx0gcr),
|
||||
DDRPHY_REG_REG(dx1gcr),
|
||||
DDRPHY_REG_REG(dx2gcr),
|
||||
DDRPHY_REG_REG(dx3gcr),
|
||||
};
|
||||
|
||||
#define DDRPHY_REG_TIMING(x) DDRPHY_REG(x, stm32mp1_ddrphy_timing)
|
||||
static const struct reg_desc ddrphy_timing[DDRPHY_REG_TIMING_SIZE] = {
|
||||
DDRPHY_REG_TIMING(ptr0),
|
||||
DDRPHY_REG_TIMING(ptr1),
|
||||
DDRPHY_REG_TIMING(ptr2),
|
||||
DDRPHY_REG_TIMING(dtpr0),
|
||||
DDRPHY_REG_TIMING(dtpr1),
|
||||
DDRPHY_REG_TIMING(dtpr2),
|
||||
DDRPHY_REG_TIMING(mr0),
|
||||
DDRPHY_REG_TIMING(mr1),
|
||||
DDRPHY_REG_TIMING(mr2),
|
||||
DDRPHY_REG_TIMING(mr3),
|
||||
};
|
||||
|
||||
#define DDRPHY_REG_CAL(x) DDRPHY_REG(x, stm32mp1_ddrphy_cal)
|
||||
static const struct reg_desc ddrphy_cal[DDRPHY_REG_CAL_SIZE] = {
|
||||
DDRPHY_REG_CAL(dx0dllcr),
|
||||
DDRPHY_REG_CAL(dx0dqtr),
|
||||
DDRPHY_REG_CAL(dx0dqstr),
|
||||
DDRPHY_REG_CAL(dx1dllcr),
|
||||
DDRPHY_REG_CAL(dx1dqtr),
|
||||
DDRPHY_REG_CAL(dx1dqstr),
|
||||
DDRPHY_REG_CAL(dx2dllcr),
|
||||
DDRPHY_REG_CAL(dx2dqtr),
|
||||
DDRPHY_REG_CAL(dx2dqstr),
|
||||
DDRPHY_REG_CAL(dx3dllcr),
|
||||
DDRPHY_REG_CAL(dx3dqtr),
|
||||
DDRPHY_REG_CAL(dx3dqstr),
|
||||
};
|
||||
|
||||
/**************************************************************
|
||||
* DYNAMIC REGISTERS: only used for debug purpose (read/modify)
|
||||
**************************************************************/
|
||||
#ifdef CONFIG_STM32MP1_DDR_INTERACTIVE
|
||||
static const struct reg_desc ddr_dyn[] = {
|
||||
DDR_REG_DYN(stat),
|
||||
DDR_REG_DYN(init0),
|
||||
DDR_REG_DYN(dfimisc),
|
||||
DDR_REG_DYN(dfistat),
|
||||
DDR_REG_DYN(swctl),
|
||||
DDR_REG_DYN(swstat),
|
||||
DDR_REG_DYN(pctrl_0),
|
||||
DDR_REG_DYN(pctrl_1),
|
||||
};
|
||||
|
||||
#define DDR_REG_DYN_SIZE ARRAY_SIZE(ddr_dyn)
|
||||
|
||||
static const struct reg_desc ddrphy_dyn[] = {
|
||||
DDRPHY_REG_DYN(pir),
|
||||
DDRPHY_REG_DYN(pgsr),
|
||||
DDRPHY_REG_DYN(zq0sr0),
|
||||
DDRPHY_REG_DYN(zq0sr1),
|
||||
DDRPHY_REG_DYN(dx0gsr0),
|
||||
DDRPHY_REG_DYN(dx0gsr1),
|
||||
DDRPHY_REG_DYN(dx1gsr0),
|
||||
DDRPHY_REG_DYN(dx1gsr1),
|
||||
DDRPHY_REG_DYN(dx2gsr0),
|
||||
DDRPHY_REG_DYN(dx2gsr1),
|
||||
DDRPHY_REG_DYN(dx3gsr0),
|
||||
DDRPHY_REG_DYN(dx3gsr1),
|
||||
};
|
||||
|
||||
#define DDRPHY_REG_DYN_SIZE ARRAY_SIZE(ddrphy_dyn)
|
||||
|
||||
#endif
|
||||
|
||||
/*****************************************************************
|
||||
* REGISTERS ARRAY: used to parse device tree and interactive mode
|
||||
*****************************************************************/
|
||||
enum reg_type {
|
||||
REG_REG,
|
||||
REG_TIMING,
|
||||
REG_PERF,
|
||||
REG_MAP,
|
||||
REGPHY_REG,
|
||||
REGPHY_TIMING,
|
||||
REGPHY_CAL,
|
||||
#ifdef CONFIG_STM32MP1_DDR_INTERACTIVE
|
||||
/* dynamic registers => managed in driver or not changed,
|
||||
* can be dumped in interactive mode
|
||||
*/
|
||||
REG_DYN,
|
||||
REGPHY_DYN,
|
||||
#endif
|
||||
REG_TYPE_NB
|
||||
};
|
||||
|
||||
enum base_type {
|
||||
DDR_BASE,
|
||||
DDRPHY_BASE,
|
||||
NONE_BASE
|
||||
};
|
||||
|
||||
struct ddr_reg_info {
|
||||
const char *name;
|
||||
const struct reg_desc *desc;
|
||||
u8 size;
|
||||
enum base_type base;
|
||||
};
|
||||
|
||||
#define DDRPHY_REG_CAL(x) DDRPHY_REG(x, stm32mp1_ddrphy_cal)
|
||||
|
||||
const struct ddr_reg_info ddr_registers[REG_TYPE_NB] = {
|
||||
[REG_REG] = {
|
||||
"static", ddr_reg, DDRCTL_REG_REG_SIZE, DDR_BASE},
|
||||
[REG_TIMING] = {
|
||||
"timing", ddr_timing, DDRCTL_REG_TIMING_SIZE, DDR_BASE},
|
||||
[REG_PERF] = {
|
||||
"perf", ddr_perf, DDRCTL_REG_PERF_SIZE, DDR_BASE},
|
||||
[REG_MAP] = {
|
||||
"map", ddr_map, DDRCTL_REG_MAP_SIZE, DDR_BASE},
|
||||
[REGPHY_REG] = {
|
||||
"static", ddrphy_reg, DDRPHY_REG_REG_SIZE, DDRPHY_BASE},
|
||||
[REGPHY_TIMING] = {
|
||||
"timing", ddrphy_timing, DDRPHY_REG_TIMING_SIZE, DDRPHY_BASE},
|
||||
[REGPHY_CAL] = {
|
||||
"cal", ddrphy_cal, DDRPHY_REG_CAL_SIZE, DDRPHY_BASE},
|
||||
#ifdef CONFIG_STM32MP1_DDR_INTERACTIVE
|
||||
[REG_DYN] = {
|
||||
"dyn", ddr_dyn, DDR_REG_DYN_SIZE, DDR_BASE},
|
||||
[REGPHY_DYN] = {
|
||||
"dyn", ddrphy_dyn, DDRPHY_REG_DYN_SIZE, DDRPHY_BASE},
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
const char *base_name[] = {
|
||||
[DDR_BASE] = "ctl",
|
||||
[DDRPHY_BASE] = "phy",
|
||||
};
|
||||
|
||||
static u32 get_base_addr(const struct ddr_info *priv, enum base_type base)
|
||||
{
|
||||
if (base == DDRPHY_BASE)
|
||||
return (u32)priv->phy;
|
||||
else
|
||||
return (u32)priv->ctl;
|
||||
}
|
||||
|
||||
static void set_reg(const struct ddr_info *priv,
|
||||
enum reg_type type,
|
||||
const void *param)
|
||||
{
|
||||
unsigned int i;
|
||||
unsigned int *ptr, value;
|
||||
enum base_type base = ddr_registers[type].base;
|
||||
u32 base_addr = get_base_addr(priv, base);
|
||||
const struct reg_desc *desc = ddr_registers[type].desc;
|
||||
|
||||
debug("init %s\n", ddr_registers[type].name);
|
||||
for (i = 0; i < ddr_registers[type].size; i++) {
|
||||
ptr = (unsigned int *)(base_addr + desc[i].offset);
|
||||
if (desc[i].par_offset == INVALID_OFFSET) {
|
||||
pr_err("invalid parameter offset for %s", desc[i].name);
|
||||
} else {
|
||||
value = *((u32 *)((u32)param +
|
||||
desc[i].par_offset));
|
||||
writel(value, ptr);
|
||||
debug("[0x%x] %s= 0x%08x\n",
|
||||
(u32)ptr, desc[i].name, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_STM32MP1_DDR_INTERACTIVE
|
||||
static void stm32mp1_dump_reg_desc(u32 base_addr, const struct reg_desc *desc)
|
||||
{
|
||||
unsigned int *ptr;
|
||||
|
||||
ptr = (unsigned int *)(base_addr + desc->offset);
|
||||
printf("%s= 0x%08x\n", desc->name, readl(ptr));
|
||||
}
|
||||
|
||||
static void stm32mp1_dump_param_desc(u32 par_addr, const struct reg_desc *desc)
|
||||
{
|
||||
unsigned int *ptr;
|
||||
|
||||
ptr = (unsigned int *)(par_addr + desc->par_offset);
|
||||
printf("%s= 0x%08x\n", desc->name, readl(ptr));
|
||||
}
|
||||
|
||||
static const struct reg_desc *found_reg(const char *name, enum reg_type *type)
|
||||
{
|
||||
unsigned int i, j;
|
||||
const struct reg_desc *desc;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(ddr_registers); i++) {
|
||||
desc = ddr_registers[i].desc;
|
||||
for (j = 0; j < ddr_registers[i].size; j++) {
|
||||
if (strcmp(name, desc[j].name) == 0) {
|
||||
*type = i;
|
||||
return &desc[j];
|
||||
}
|
||||
}
|
||||
}
|
||||
*type = REG_TYPE_NB;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int stm32mp1_dump_reg(const struct ddr_info *priv,
|
||||
const char *name)
|
||||
{
|
||||
unsigned int i, j;
|
||||
const struct reg_desc *desc;
|
||||
u32 base_addr;
|
||||
enum base_type p_base;
|
||||
enum reg_type type;
|
||||
const char *p_name;
|
||||
enum base_type filter = NONE_BASE;
|
||||
int result = -1;
|
||||
|
||||
if (name) {
|
||||
if (strcmp(name, base_name[DDR_BASE]) == 0)
|
||||
filter = DDR_BASE;
|
||||
else if (strcmp(name, base_name[DDRPHY_BASE]) == 0)
|
||||
filter = DDRPHY_BASE;
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(ddr_registers); i++) {
|
||||
p_base = ddr_registers[i].base;
|
||||
p_name = ddr_registers[i].name;
|
||||
if (!name || (filter == p_base || !strcmp(name, p_name))) {
|
||||
result = 0;
|
||||
desc = ddr_registers[i].desc;
|
||||
base_addr = get_base_addr(priv, p_base);
|
||||
printf("==%s.%s==\n", base_name[p_base], p_name);
|
||||
for (j = 0; j < ddr_registers[i].size; j++)
|
||||
stm32mp1_dump_reg_desc(base_addr, &desc[j]);
|
||||
}
|
||||
}
|
||||
if (result) {
|
||||
desc = found_reg(name, &type);
|
||||
if (desc) {
|
||||
p_base = ddr_registers[type].base;
|
||||
base_addr = get_base_addr(priv, p_base);
|
||||
stm32mp1_dump_reg_desc(base_addr, desc);
|
||||
result = 0;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void stm32mp1_edit_reg(const struct ddr_info *priv,
|
||||
char *name, char *string)
|
||||
{
|
||||
unsigned long *ptr, value;
|
||||
enum reg_type type;
|
||||
enum base_type base;
|
||||
const struct reg_desc *desc;
|
||||
u32 base_addr;
|
||||
|
||||
desc = found_reg(name, &type);
|
||||
|
||||
if (!desc) {
|
||||
printf("%s not found\n", name);
|
||||
return;
|
||||
}
|
||||
if (strict_strtoul(string, 16, &value) < 0) {
|
||||
printf("invalid value %s\n", string);
|
||||
return;
|
||||
}
|
||||
base = ddr_registers[type].base;
|
||||
base_addr = get_base_addr(priv, base);
|
||||
ptr = (unsigned long *)(base_addr + desc->offset);
|
||||
writel(value, ptr);
|
||||
printf("%s= 0x%08x\n", desc->name, readl(ptr));
|
||||
}
|
||||
|
||||
static u32 get_par_addr(const struct stm32mp1_ddr_config *config,
|
||||
enum reg_type type)
|
||||
{
|
||||
u32 par_addr = 0x0;
|
||||
|
||||
switch (type) {
|
||||
case REG_REG:
|
||||
par_addr = (u32)&config->c_reg;
|
||||
break;
|
||||
case REG_TIMING:
|
||||
par_addr = (u32)&config->c_timing;
|
||||
break;
|
||||
case REG_PERF:
|
||||
par_addr = (u32)&config->c_perf;
|
||||
break;
|
||||
case REG_MAP:
|
||||
par_addr = (u32)&config->c_map;
|
||||
break;
|
||||
case REGPHY_REG:
|
||||
par_addr = (u32)&config->p_reg;
|
||||
break;
|
||||
case REGPHY_TIMING:
|
||||
par_addr = (u32)&config->p_timing;
|
||||
break;
|
||||
case REGPHY_CAL:
|
||||
par_addr = (u32)&config->p_cal;
|
||||
break;
|
||||
case REG_DYN:
|
||||
case REGPHY_DYN:
|
||||
case REG_TYPE_NB:
|
||||
par_addr = (u32)NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
return par_addr;
|
||||
}
|
||||
|
||||
int stm32mp1_dump_param(const struct stm32mp1_ddr_config *config,
|
||||
const char *name)
|
||||
{
|
||||
unsigned int i, j;
|
||||
const struct reg_desc *desc;
|
||||
u32 par_addr;
|
||||
enum base_type p_base;
|
||||
enum reg_type type;
|
||||
const char *p_name;
|
||||
enum base_type filter = NONE_BASE;
|
||||
int result = -EINVAL;
|
||||
|
||||
if (name) {
|
||||
if (strcmp(name, base_name[DDR_BASE]) == 0)
|
||||
filter = DDR_BASE;
|
||||
else if (strcmp(name, base_name[DDRPHY_BASE]) == 0)
|
||||
filter = DDRPHY_BASE;
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(ddr_registers); i++) {
|
||||
par_addr = get_par_addr(config, i);
|
||||
if (!par_addr)
|
||||
continue;
|
||||
p_base = ddr_registers[i].base;
|
||||
p_name = ddr_registers[i].name;
|
||||
if (!name || (filter == p_base || !strcmp(name, p_name))) {
|
||||
result = 0;
|
||||
desc = ddr_registers[i].desc;
|
||||
printf("==%s.%s==\n", base_name[p_base], p_name);
|
||||
for (j = 0; j < ddr_registers[i].size; j++)
|
||||
stm32mp1_dump_param_desc(par_addr, &desc[j]);
|
||||
}
|
||||
}
|
||||
if (result) {
|
||||
desc = found_reg(name, &type);
|
||||
if (desc) {
|
||||
par_addr = get_par_addr(config, type);
|
||||
if (par_addr) {
|
||||
stm32mp1_dump_param_desc(par_addr, desc);
|
||||
result = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void stm32mp1_edit_param(const struct stm32mp1_ddr_config *config,
|
||||
char *name, char *string)
|
||||
{
|
||||
unsigned long *ptr, value;
|
||||
enum reg_type type;
|
||||
const struct reg_desc *desc;
|
||||
u32 par_addr;
|
||||
|
||||
desc = found_reg(name, &type);
|
||||
if (!desc) {
|
||||
printf("%s not found\n", name);
|
||||
return;
|
||||
}
|
||||
if (strict_strtoul(string, 16, &value) < 0) {
|
||||
printf("invalid value %s\n", string);
|
||||
return;
|
||||
}
|
||||
par_addr = get_par_addr(config, type);
|
||||
if (!par_addr) {
|
||||
printf("no parameter %s\n", name);
|
||||
return;
|
||||
}
|
||||
ptr = (unsigned long *)(par_addr + desc->par_offset);
|
||||
writel(value, ptr);
|
||||
printf("%s= 0x%08x\n", desc->name, readl(ptr));
|
||||
}
|
||||
#endif
|
||||
|
||||
__weak bool stm32mp1_ddr_interactive(void *priv,
|
||||
enum stm32mp1_ddr_interact_step step,
|
||||
const struct stm32mp1_ddr_config *config)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
#define INTERACTIVE(step)\
|
||||
stm32mp1_ddr_interactive(priv, step, config)
|
||||
|
||||
static void ddrphy_idone_wait(struct stm32mp1_ddrphy *phy)
|
||||
{
|
||||
u32 pgsr;
|
||||
int ret;
|
||||
|
||||
ret = readl_poll_timeout(&phy->pgsr, pgsr,
|
||||
pgsr & (DDRPHYC_PGSR_IDONE |
|
||||
DDRPHYC_PGSR_DTERR |
|
||||
DDRPHYC_PGSR_DTIERR |
|
||||
DDRPHYC_PGSR_DFTERR |
|
||||
DDRPHYC_PGSR_RVERR |
|
||||
DDRPHYC_PGSR_RVEIRR),
|
||||
1000000);
|
||||
debug("\n[0x%08x] pgsr = 0x%08x ret=%d\n",
|
||||
(u32)&phy->pgsr, pgsr, ret);
|
||||
}
|
||||
|
||||
void stm32mp1_ddrphy_init(struct stm32mp1_ddrphy *phy, u32 pir)
|
||||
{
|
||||
pir |= DDRPHYC_PIR_INIT;
|
||||
writel(pir, &phy->pir);
|
||||
debug("[0x%08x] pir = 0x%08x -> 0x%08x\n",
|
||||
(u32)&phy->pir, pir, readl(&phy->pir));
|
||||
|
||||
/* need to wait 10 configuration clock before start polling */
|
||||
udelay(10);
|
||||
|
||||
/* Wait DRAM initialization and Gate Training Evaluation complete */
|
||||
ddrphy_idone_wait(phy);
|
||||
}
|
||||
|
||||
/* start quasi dynamic register update */
|
||||
static void start_sw_done(struct stm32mp1_ddrctl *ctl)
|
||||
{
|
||||
clrbits_le32(&ctl->swctl, DDRCTRL_SWCTL_SW_DONE);
|
||||
}
|
||||
|
||||
/* wait quasi dynamic register update */
|
||||
static void wait_sw_done_ack(struct stm32mp1_ddrctl *ctl)
|
||||
{
|
||||
int ret;
|
||||
u32 swstat;
|
||||
|
||||
setbits_le32(&ctl->swctl, DDRCTRL_SWCTL_SW_DONE);
|
||||
|
||||
ret = readl_poll_timeout(&ctl->swstat, swstat,
|
||||
swstat & DDRCTRL_SWSTAT_SW_DONE_ACK,
|
||||
1000000);
|
||||
if (ret)
|
||||
panic("Timeout initialising DRAM : DDR->swstat = %x\n",
|
||||
swstat);
|
||||
|
||||
debug("[0x%08x] swstat = 0x%08x\n", (u32)&ctl->swstat, swstat);
|
||||
}
|
||||
|
||||
/* wait quasi dynamic register update */
|
||||
static void wait_operating_mode(struct ddr_info *priv, int mode)
|
||||
{
|
||||
u32 stat, val, mask, val2 = 0, mask2 = 0;
|
||||
int ret;
|
||||
|
||||
mask = DDRCTRL_STAT_OPERATING_MODE_MASK;
|
||||
val = mode;
|
||||
/* self-refresh due to software => check also STAT.selfref_type */
|
||||
if (mode == DDRCTRL_STAT_OPERATING_MODE_SR) {
|
||||
mask |= DDRCTRL_STAT_SELFREF_TYPE_MASK;
|
||||
val |= DDRCTRL_STAT_SELFREF_TYPE_SR;
|
||||
} else if (mode == DDRCTRL_STAT_OPERATING_MODE_NORMAL) {
|
||||
/* normal mode: handle also automatic self refresh */
|
||||
mask2 = DDRCTRL_STAT_OPERATING_MODE_MASK |
|
||||
DDRCTRL_STAT_SELFREF_TYPE_MASK;
|
||||
val2 = DDRCTRL_STAT_OPERATING_MODE_SR |
|
||||
DDRCTRL_STAT_SELFREF_TYPE_ASR;
|
||||
}
|
||||
|
||||
ret = readl_poll_timeout(&priv->ctl->stat, stat,
|
||||
((stat & mask) == val) ||
|
||||
(mask2 && ((stat & mask2) == val2)),
|
||||
1000000);
|
||||
|
||||
if (ret)
|
||||
panic("Timeout DRAM : DDR->stat = %x\n", stat);
|
||||
|
||||
debug("[0x%08x] stat = 0x%08x\n", (u32)&priv->ctl->stat, stat);
|
||||
}
|
||||
|
||||
void stm32mp1_refresh_disable(struct stm32mp1_ddrctl *ctl)
|
||||
{
|
||||
start_sw_done(ctl);
|
||||
/* quasi-dynamic register update*/
|
||||
setbits_le32(&ctl->rfshctl3, DDRCTRL_RFSHCTL3_DIS_AUTO_REFRESH);
|
||||
clrbits_le32(&ctl->pwrctl, DDRCTRL_PWRCTL_POWERDOWN_EN);
|
||||
clrbits_le32(&ctl->dfimisc, DDRCTRL_DFIMISC_DFI_INIT_COMPLETE_EN);
|
||||
wait_sw_done_ack(ctl);
|
||||
}
|
||||
|
||||
void stm32mp1_refresh_restore(struct stm32mp1_ddrctl *ctl,
|
||||
u32 rfshctl3, u32 pwrctl)
|
||||
{
|
||||
start_sw_done(ctl);
|
||||
if (!(rfshctl3 & DDRCTRL_RFSHCTL3_DIS_AUTO_REFRESH))
|
||||
clrbits_le32(&ctl->rfshctl3, DDRCTRL_RFSHCTL3_DIS_AUTO_REFRESH);
|
||||
if (pwrctl & DDRCTRL_PWRCTL_POWERDOWN_EN)
|
||||
setbits_le32(&ctl->pwrctl, DDRCTRL_PWRCTL_POWERDOWN_EN);
|
||||
setbits_le32(&ctl->dfimisc, DDRCTRL_DFIMISC_DFI_INIT_COMPLETE_EN);
|
||||
wait_sw_done_ack(ctl);
|
||||
}
|
||||
|
||||
/* board-specific DDR power initializations. */
|
||||
__weak int board_ddr_power_init(enum ddr_type ddr_type)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
__maybe_unused
|
||||
void stm32mp1_ddr_init(struct ddr_info *priv,
|
||||
const struct stm32mp1_ddr_config *config)
|
||||
{
|
||||
u32 pir;
|
||||
int ret = -EINVAL;
|
||||
|
||||
if (config->c_reg.mstr & DDRCTRL_MSTR_DDR3)
|
||||
ret = board_ddr_power_init(STM32MP_DDR3);
|
||||
else if (config->c_reg.mstr & DDRCTRL_MSTR_LPDDR2)
|
||||
ret = board_ddr_power_init(STM32MP_LPDDR2);
|
||||
else if (config->c_reg.mstr & DDRCTRL_MSTR_LPDDR3)
|
||||
ret = board_ddr_power_init(STM32MP_LPDDR3);
|
||||
|
||||
if (ret)
|
||||
panic("ddr power init failed\n");
|
||||
|
||||
start:
|
||||
debug("name = %s\n", config->info.name);
|
||||
debug("speed = %d kHz\n", config->info.speed);
|
||||
debug("size = 0x%x\n", config->info.size);
|
||||
/*
|
||||
* 1. Program the DWC_ddr_umctl2 registers
|
||||
* 1.1 RESETS: presetn, core_ddrc_rstn, aresetn
|
||||
*/
|
||||
/* Assert All DDR part */
|
||||
setbits_le32(priv->rcc + RCC_DDRITFCR, RCC_DDRITFCR_DDRCAPBRST);
|
||||
setbits_le32(priv->rcc + RCC_DDRITFCR, RCC_DDRITFCR_DDRCAXIRST);
|
||||
setbits_le32(priv->rcc + RCC_DDRITFCR, RCC_DDRITFCR_DDRCORERST);
|
||||
setbits_le32(priv->rcc + RCC_DDRITFCR, RCC_DDRITFCR_DPHYAPBRST);
|
||||
setbits_le32(priv->rcc + RCC_DDRITFCR, RCC_DDRITFCR_DPHYRST);
|
||||
setbits_le32(priv->rcc + RCC_DDRITFCR, RCC_DDRITFCR_DPHYCTLRST);
|
||||
|
||||
/* 1.2. start CLOCK */
|
||||
if (stm32mp1_ddr_clk_enable(priv, config->info.speed))
|
||||
panic("invalid DRAM clock : %d kHz\n",
|
||||
config->info.speed);
|
||||
|
||||
/* 1.3. deassert reset */
|
||||
/* de-assert PHY rstn and ctl_rstn via DPHYRST and DPHYCTLRST */
|
||||
clrbits_le32(priv->rcc + RCC_DDRITFCR, RCC_DDRITFCR_DPHYRST);
|
||||
clrbits_le32(priv->rcc + RCC_DDRITFCR, RCC_DDRITFCR_DPHYCTLRST);
|
||||
/* De-assert presetn once the clocks are active
|
||||
* and stable via DDRCAPBRST bit
|
||||
*/
|
||||
clrbits_le32(priv->rcc + RCC_DDRITFCR, RCC_DDRITFCR_DDRCAPBRST);
|
||||
|
||||
/* 1.4. wait 128 cycles to permit initialization of end logic */
|
||||
udelay(2);
|
||||
/* for PCLK = 133MHz => 1 us is enough, 2 to allow lower frequency */
|
||||
|
||||
if (INTERACTIVE(STEP_DDR_RESET))
|
||||
goto start;
|
||||
|
||||
/* 1.5. initialize registers ddr_umctl2 */
|
||||
/* Stop uMCTL2 before PHY is ready */
|
||||
clrbits_le32(&priv->ctl->dfimisc, DDRCTRL_DFIMISC_DFI_INIT_COMPLETE_EN);
|
||||
debug("[0x%08x] dfimisc = 0x%08x\n",
|
||||
(u32)&priv->ctl->dfimisc, readl(&priv->ctl->dfimisc));
|
||||
|
||||
set_reg(priv, REG_REG, &config->c_reg);
|
||||
set_reg(priv, REG_TIMING, &config->c_timing);
|
||||
set_reg(priv, REG_MAP, &config->c_map);
|
||||
|
||||
/* skip CTRL init, SDRAM init is done by PHY PUBL */
|
||||
clrsetbits_le32(&priv->ctl->init0,
|
||||
DDRCTRL_INIT0_SKIP_DRAM_INIT_MASK,
|
||||
DDRCTRL_INIT0_SKIP_DRAM_INIT_NORMAL);
|
||||
|
||||
set_reg(priv, REG_PERF, &config->c_perf);
|
||||
|
||||
if (INTERACTIVE(STEP_CTL_INIT))
|
||||
goto start;
|
||||
|
||||
/* 2. deassert reset signal core_ddrc_rstn, aresetn and presetn */
|
||||
clrbits_le32(priv->rcc + RCC_DDRITFCR, RCC_DDRITFCR_DDRCORERST);
|
||||
clrbits_le32(priv->rcc + RCC_DDRITFCR, RCC_DDRITFCR_DDRCAXIRST);
|
||||
clrbits_le32(priv->rcc + RCC_DDRITFCR, RCC_DDRITFCR_DPHYAPBRST);
|
||||
|
||||
/* 3. start PHY init by accessing relevant PUBL registers
|
||||
* (DXGCR, DCR, PTR*, MR*, DTPR*)
|
||||
*/
|
||||
set_reg(priv, REGPHY_REG, &config->p_reg);
|
||||
set_reg(priv, REGPHY_TIMING, &config->p_timing);
|
||||
set_reg(priv, REGPHY_CAL, &config->p_cal);
|
||||
|
||||
if (INTERACTIVE(STEP_PHY_INIT))
|
||||
goto start;
|
||||
|
||||
/* 4. Monitor PHY init status by polling PUBL register PGSR.IDONE
|
||||
* Perform DDR PHY DRAM initialization and Gate Training Evaluation
|
||||
*/
|
||||
ddrphy_idone_wait(priv->phy);
|
||||
|
||||
/* 5. Indicate to PUBL that controller performs SDRAM initialization
|
||||
* by setting PIR.INIT and PIR CTLDINIT and pool PGSR.IDONE
|
||||
* DRAM init is done by PHY, init0.skip_dram.init = 1
|
||||
*/
|
||||
pir = DDRPHYC_PIR_DLLSRST | DDRPHYC_PIR_DLLLOCK | DDRPHYC_PIR_ZCAL |
|
||||
DDRPHYC_PIR_ITMSRST | DDRPHYC_PIR_DRAMINIT | DDRPHYC_PIR_ICPC;
|
||||
|
||||
if (config->c_reg.mstr & DDRCTRL_MSTR_DDR3)
|
||||
pir |= DDRPHYC_PIR_DRAMRST; /* only for DDR3 */
|
||||
|
||||
stm32mp1_ddrphy_init(priv->phy, pir);
|
||||
|
||||
/* 6. SET DFIMISC.dfi_init_complete_en to 1 */
|
||||
/* Enable quasi-dynamic register programming*/
|
||||
start_sw_done(priv->ctl);
|
||||
setbits_le32(&priv->ctl->dfimisc, DDRCTRL_DFIMISC_DFI_INIT_COMPLETE_EN);
|
||||
wait_sw_done_ack(priv->ctl);
|
||||
|
||||
/* 7. Wait for DWC_ddr_umctl2 to move to normal operation mode
|
||||
* by monitoring STAT.operating_mode signal
|
||||
*/
|
||||
/* wait uMCTL2 ready */
|
||||
|
||||
wait_operating_mode(priv, DDRCTRL_STAT_OPERATING_MODE_NORMAL);
|
||||
|
||||
debug("DDR DQS training : ");
|
||||
/* 8. Disable Auto refresh and power down by setting
|
||||
* - RFSHCTL3.dis_au_refresh = 1
|
||||
* - PWRCTL.powerdown_en = 0
|
||||
* - DFIMISC.dfiinit_complete_en = 0
|
||||
*/
|
||||
stm32mp1_refresh_disable(priv->ctl);
|
||||
|
||||
/* 9. Program PUBL PGCR to enable refresh during training and rank to train
|
||||
* not done => keep the programed value in PGCR
|
||||
*/
|
||||
|
||||
/* 10. configure PUBL PIR register to specify which training step to run */
|
||||
/* warning : RVTRN is not supported by this PUBL */
|
||||
stm32mp1_ddrphy_init(priv->phy, DDRPHYC_PIR_QSTRN);
|
||||
|
||||
/* 11. monitor PUB PGSR.IDONE to poll cpmpletion of training sequence */
|
||||
ddrphy_idone_wait(priv->phy);
|
||||
|
||||
/* 12. set back registers in step 8 to the orginal values if desidered */
|
||||
stm32mp1_refresh_restore(priv->ctl, config->c_reg.rfshctl3,
|
||||
config->c_reg.pwrctl);
|
||||
|
||||
/* enable uMCTL2 AXI port 0 and 1 */
|
||||
setbits_le32(&priv->ctl->pctrl_0, DDRCTRL_PCTRL_N_PORT_EN);
|
||||
setbits_le32(&priv->ctl->pctrl_1, DDRCTRL_PCTRL_N_PORT_EN);
|
||||
|
||||
if (INTERACTIVE(STEP_DDR_READY))
|
||||
goto start;
|
||||
}
|
||||
@@ -0,0 +1,205 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */
|
||||
/*
|
||||
* Copyright (C) 2018, STMicroelectronics - All Rights Reserved
|
||||
*/
|
||||
|
||||
#ifndef _RAM_STM32MP1_DDR_H
|
||||
#define _RAM_STM32MP1_DDR_H
|
||||
|
||||
enum stm32mp1_ddr_interact_step {
|
||||
STEP_DDR_RESET,
|
||||
STEP_CTL_INIT,
|
||||
STEP_PHY_INIT,
|
||||
STEP_DDR_READY,
|
||||
STEP_RUN,
|
||||
};
|
||||
|
||||
/* DDR CTL and DDR PHY REGISTERS */
|
||||
struct stm32mp1_ddrctl;
|
||||
struct stm32mp1_ddrphy;
|
||||
|
||||
/**
|
||||
* struct ddr_info
|
||||
*
|
||||
* @dev: pointer for the device
|
||||
* @info: UCLASS RAM information
|
||||
* @ctl: DDR controleur base address
|
||||
* @clk: DDR clock
|
||||
* @phy: DDR PHY base address
|
||||
* @rcc: rcc base address
|
||||
*/
|
||||
struct ddr_info {
|
||||
struct udevice *dev;
|
||||
struct ram_info info;
|
||||
struct clk clk;
|
||||
struct stm32mp1_ddrctl *ctl;
|
||||
struct stm32mp1_ddrphy *phy;
|
||||
u32 rcc;
|
||||
};
|
||||
|
||||
struct stm32mp1_ddrctrl_reg {
|
||||
u32 mstr;
|
||||
u32 mrctrl0;
|
||||
u32 mrctrl1;
|
||||
u32 derateen;
|
||||
u32 derateint;
|
||||
u32 pwrctl;
|
||||
u32 pwrtmg;
|
||||
u32 hwlpctl;
|
||||
u32 rfshctl0;
|
||||
u32 rfshctl3;
|
||||
u32 crcparctl0;
|
||||
u32 zqctl0;
|
||||
u32 dfitmg0;
|
||||
u32 dfitmg1;
|
||||
u32 dfilpcfg0;
|
||||
u32 dfiupd0;
|
||||
u32 dfiupd1;
|
||||
u32 dfiupd2;
|
||||
u32 dfiphymstr;
|
||||
u32 odtmap;
|
||||
u32 dbg0;
|
||||
u32 dbg1;
|
||||
u32 dbgcmd;
|
||||
u32 poisoncfg;
|
||||
u32 pccfg;
|
||||
|
||||
};
|
||||
|
||||
struct stm32mp1_ddrctrl_timing {
|
||||
u32 rfshtmg;
|
||||
u32 dramtmg0;
|
||||
u32 dramtmg1;
|
||||
u32 dramtmg2;
|
||||
u32 dramtmg3;
|
||||
u32 dramtmg4;
|
||||
u32 dramtmg5;
|
||||
u32 dramtmg6;
|
||||
u32 dramtmg7;
|
||||
u32 dramtmg8;
|
||||
u32 dramtmg14;
|
||||
u32 odtcfg;
|
||||
};
|
||||
|
||||
struct stm32mp1_ddrctrl_map {
|
||||
u32 addrmap1;
|
||||
u32 addrmap2;
|
||||
u32 addrmap3;
|
||||
u32 addrmap4;
|
||||
u32 addrmap5;
|
||||
u32 addrmap6;
|
||||
u32 addrmap9;
|
||||
u32 addrmap10;
|
||||
u32 addrmap11;
|
||||
};
|
||||
|
||||
struct stm32mp1_ddrctrl_perf {
|
||||
u32 sched;
|
||||
u32 sched1;
|
||||
u32 perfhpr1;
|
||||
u32 perflpr1;
|
||||
u32 perfwr1;
|
||||
u32 pcfgr_0;
|
||||
u32 pcfgw_0;
|
||||
u32 pcfgqos0_0;
|
||||
u32 pcfgqos1_0;
|
||||
u32 pcfgwqos0_0;
|
||||
u32 pcfgwqos1_0;
|
||||
u32 pcfgr_1;
|
||||
u32 pcfgw_1;
|
||||
u32 pcfgqos0_1;
|
||||
u32 pcfgqos1_1;
|
||||
u32 pcfgwqos0_1;
|
||||
u32 pcfgwqos1_1;
|
||||
};
|
||||
|
||||
struct stm32mp1_ddrphy_reg {
|
||||
u32 pgcr;
|
||||
u32 aciocr;
|
||||
u32 dxccr;
|
||||
u32 dsgcr;
|
||||
u32 dcr;
|
||||
u32 odtcr;
|
||||
u32 zq0cr1;
|
||||
u32 dx0gcr;
|
||||
u32 dx1gcr;
|
||||
u32 dx2gcr;
|
||||
u32 dx3gcr;
|
||||
};
|
||||
|
||||
struct stm32mp1_ddrphy_timing {
|
||||
u32 ptr0;
|
||||
u32 ptr1;
|
||||
u32 ptr2;
|
||||
u32 dtpr0;
|
||||
u32 dtpr1;
|
||||
u32 dtpr2;
|
||||
u32 mr0;
|
||||
u32 mr1;
|
||||
u32 mr2;
|
||||
u32 mr3;
|
||||
};
|
||||
|
||||
struct stm32mp1_ddrphy_cal {
|
||||
u32 dx0dllcr;
|
||||
u32 dx0dqtr;
|
||||
u32 dx0dqstr;
|
||||
u32 dx1dllcr;
|
||||
u32 dx1dqtr;
|
||||
u32 dx1dqstr;
|
||||
u32 dx2dllcr;
|
||||
u32 dx2dqtr;
|
||||
u32 dx2dqstr;
|
||||
u32 dx3dllcr;
|
||||
u32 dx3dqtr;
|
||||
u32 dx3dqstr;
|
||||
};
|
||||
|
||||
struct stm32mp1_ddr_info {
|
||||
const char *name;
|
||||
u32 speed; /* in kHZ */
|
||||
u32 size; /* memory size in byte = col * row * width */
|
||||
};
|
||||
|
||||
struct stm32mp1_ddr_config {
|
||||
struct stm32mp1_ddr_info info;
|
||||
struct stm32mp1_ddrctrl_reg c_reg;
|
||||
struct stm32mp1_ddrctrl_timing c_timing;
|
||||
struct stm32mp1_ddrctrl_map c_map;
|
||||
struct stm32mp1_ddrctrl_perf c_perf;
|
||||
struct stm32mp1_ddrphy_reg p_reg;
|
||||
struct stm32mp1_ddrphy_timing p_timing;
|
||||
struct stm32mp1_ddrphy_cal p_cal;
|
||||
};
|
||||
|
||||
int stm32mp1_ddr_clk_enable(struct ddr_info *priv, u32 mem_speed);
|
||||
void stm32mp1_ddrphy_init(struct stm32mp1_ddrphy *phy, u32 pir);
|
||||
void stm32mp1_refresh_disable(struct stm32mp1_ddrctl *ctl);
|
||||
void stm32mp1_refresh_restore(struct stm32mp1_ddrctl *ctl,
|
||||
u32 rfshctl3,
|
||||
u32 pwrctl);
|
||||
|
||||
void stm32mp1_ddr_init(
|
||||
struct ddr_info *priv,
|
||||
const struct stm32mp1_ddr_config *config);
|
||||
|
||||
int stm32mp1_dump_reg(const struct ddr_info *priv,
|
||||
const char *name);
|
||||
|
||||
void stm32mp1_edit_reg(const struct ddr_info *priv,
|
||||
char *name,
|
||||
char *string);
|
||||
|
||||
int stm32mp1_dump_param(const struct stm32mp1_ddr_config *config,
|
||||
const char *name);
|
||||
|
||||
void stm32mp1_edit_param(const struct stm32mp1_ddr_config *config,
|
||||
char *name,
|
||||
char *string);
|
||||
|
||||
bool stm32mp1_ddr_interactive(
|
||||
void *priv,
|
||||
enum stm32mp1_ddr_interact_step step,
|
||||
const struct stm32mp1_ddr_config *config);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,367 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */
|
||||
/*
|
||||
* Copyright (C) 2018, STMicroelectronics - All Rights Reserved
|
||||
*/
|
||||
|
||||
#ifndef _RAM_STM32MP1_DDR_REGS_H
|
||||
#define _RAM_STM32MP1_DDR_REGS_H
|
||||
|
||||
/* DDR3/LPDDR2/LPDDR3 Controller (DDRCTRL) registers */
|
||||
struct stm32mp1_ddrctl {
|
||||
u32 mstr ; /* 0x0 Master*/
|
||||
u32 stat; /* 0x4 Operating Mode Status*/
|
||||
u8 reserved008[0x10 - 0x8];
|
||||
u32 mrctrl0; /* 0x10 Control 0.*/
|
||||
u32 mrctrl1; /* 0x14 Control 1*/
|
||||
u32 mrstat; /* 0x18 Status*/
|
||||
u32 reserved01c; /* 0x1c */
|
||||
u32 derateen; /* 0x20 Temperature Derate Enable*/
|
||||
u32 derateint; /* 0x24 Temperature Derate Interval*/
|
||||
u8 reserved028[0x30 - 0x28];
|
||||
u32 pwrctl; /* 0x30 Low Power Control*/
|
||||
u32 pwrtmg; /* 0x34 Low Power Timing*/
|
||||
u32 hwlpctl; /* 0x38 Hardware Low Power Control*/
|
||||
u8 reserved03c[0x50 - 0x3C];
|
||||
u32 rfshctl0; /* 0x50 Refresh Control 0*/
|
||||
u32 reserved054; /* 0x54 Refresh Control 1*/
|
||||
u32 reserved058; /* 0x58 Refresh Control 2*/
|
||||
u32 reserved05C;
|
||||
u32 rfshctl3; /* 0x60 Refresh Control 0*/
|
||||
u32 rfshtmg; /* 0x64 Refresh Timing*/
|
||||
u8 reserved068[0xc0 - 0x68];
|
||||
u32 crcparctl0; /* 0xc0 CRC Parity Control0*/
|
||||
u32 reserved0c4; /* 0xc4 CRC Parity Control1*/
|
||||
u32 reserved0c8; /* 0xc8 CRC Parity Control2*/
|
||||
u32 crcparstat; /* 0xcc CRC Parity Status*/
|
||||
u32 init0; /* 0xd0 SDRAM Initialization 0*/
|
||||
u32 init1; /* 0xd4 SDRAM Initialization 1*/
|
||||
u32 init2; /* 0xd8 SDRAM Initialization 2*/
|
||||
u32 init3; /* 0xdc SDRAM Initialization 3*/
|
||||
u32 init4; /* 0xe0 SDRAM Initialization 4*/
|
||||
u32 init5; /* 0xe4 SDRAM Initialization 5*/
|
||||
u32 reserved0e8;
|
||||
u32 reserved0ec;
|
||||
u32 dimmctl; /* 0xf0 DIMM Control*/
|
||||
u8 reserved0f4[0x100 - 0xf4];
|
||||
u32 dramtmg0; /* 0x100 SDRAM Timing 0*/
|
||||
u32 dramtmg1; /* 0x104 SDRAM Timing 1*/
|
||||
u32 dramtmg2; /* 0x108 SDRAM Timing 2*/
|
||||
u32 dramtmg3; /* 0x10c SDRAM Timing 3*/
|
||||
u32 dramtmg4; /* 0x110 SDRAM Timing 4*/
|
||||
u32 dramtmg5; /* 0x114 SDRAM Timing 5*/
|
||||
u32 dramtmg6; /* 0x118 SDRAM Timing 6*/
|
||||
u32 dramtmg7; /* 0x11c SDRAM Timing 7*/
|
||||
u32 dramtmg8; /* 0x120 SDRAM Timing 8*/
|
||||
u8 reserved124[0x138 - 0x124];
|
||||
u32 dramtmg14; /* 0x138 SDRAM Timing 14*/
|
||||
u32 dramtmg15; /* 0x13C SDRAM Timing 15*/
|
||||
u8 reserved140[0x180 - 0x140];
|
||||
u32 zqctl0; /* 0x180 ZQ Control 0*/
|
||||
u32 zqctl1; /* 0x184 ZQ Control 1*/
|
||||
u32 zqctl2; /* 0x188 ZQ Control 2*/
|
||||
u32 zqstat; /* 0x18c ZQ Status*/
|
||||
u32 dfitmg0; /* 0x190 DFI Timing 0*/
|
||||
u32 dfitmg1; /* 0x194 DFI Timing 1*/
|
||||
u32 dfilpcfg0; /* 0x198 DFI Low Power Configuration 0*/
|
||||
u32 reserved19c;
|
||||
u32 dfiupd0; /* 0x1a0 DFI Update 0*/
|
||||
u32 dfiupd1; /* 0x1a4 DFI Update 1*/
|
||||
u32 dfiupd2; /* 0x1a8 DFI Update 2*/
|
||||
u32 reserved1ac;
|
||||
u32 dfimisc; /* 0x1b0 DFI Miscellaneous Control*/
|
||||
u8 reserved1b4[0x1bc - 0x1b4];
|
||||
u32 dfistat; /* 0x1bc DFI Miscellaneous Control*/
|
||||
u8 reserved1c0[0x1c4 - 0x1c0];
|
||||
u32 dfiphymstr; /* 0x1c4 DFI PHY Master interface*/
|
||||
u8 reserved1c8[0x204 - 0x1c8];
|
||||
u32 addrmap1; /* 0x204 Address Map 1*/
|
||||
u32 addrmap2; /* 0x208 Address Map 2*/
|
||||
u32 addrmap3; /* 0x20c Address Map 3*/
|
||||
u32 addrmap4; /* 0x210 Address Map 4*/
|
||||
u32 addrmap5; /* 0x214 Address Map 5*/
|
||||
u32 addrmap6; /* 0x218 Address Map 6*/
|
||||
u8 reserved21c[0x224 - 0x21c];
|
||||
u32 addrmap9; /* 0x224 Address Map 9*/
|
||||
u32 addrmap10; /* 0x228 Address Map 10*/
|
||||
u32 addrmap11; /* 0x22C Address Map 11*/
|
||||
u8 reserved230[0x240 - 0x230];
|
||||
u32 odtcfg; /* 0x240 ODT Configuration*/
|
||||
u32 odtmap; /* 0x244 ODT/Rank Map*/
|
||||
u8 reserved248[0x250 - 0x248];
|
||||
u32 sched; /* 0x250 Scheduler Control*/
|
||||
u32 sched1; /* 0x254 Scheduler Control 1*/
|
||||
u32 reserved258;
|
||||
u32 perfhpr1; /* 0x25c High Priority Read CAM 1*/
|
||||
u32 reserved260;
|
||||
u32 perflpr1; /* 0x264 Low Priority Read CAM 1*/
|
||||
u32 reserved268;
|
||||
u32 perfwr1; /* 0x26c Write CAM 1*/
|
||||
u8 reserved27c[0x300 - 0x270];
|
||||
u32 dbg0; /* 0x300 Debug 0*/
|
||||
u32 dbg1; /* 0x304 Debug 1*/
|
||||
u32 dbgcam; /* 0x308 CAM Debug*/
|
||||
u32 dbgcmd; /* 0x30c Command Debug*/
|
||||
u32 dbgstat; /* 0x310 Status Debug*/
|
||||
u8 reserved314[0x320 - 0x314];
|
||||
u32 swctl; /* 0x320 Software Programming Control Enable*/
|
||||
u32 swstat; /* 0x324 Software Programming Control Status*/
|
||||
u8 reserved328[0x36c - 0x328];
|
||||
u32 poisoncfg; /* 0x36c AXI Poison Configuration Register*/
|
||||
u32 poisonstat; /* 0x370 AXI Poison Status Register*/
|
||||
u8 reserved374[0x3fc - 0x374];
|
||||
|
||||
/* Multi Port registers */
|
||||
u32 pstat; /* 0x3fc Port Status*/
|
||||
u32 pccfg; /* 0x400 Port Common Configuration*/
|
||||
|
||||
/* PORT 0 */
|
||||
u32 pcfgr_0; /* 0x404 Configuration Read*/
|
||||
u32 pcfgw_0; /* 0x408 Configuration Write*/
|
||||
u8 reserved40c[0x490 - 0x40c];
|
||||
u32 pctrl_0; /* 0x490 Port Control Register */
|
||||
u32 pcfgqos0_0; /* 0x494 Read QoS Configuration 0*/
|
||||
u32 pcfgqos1_0; /* 0x498 Read QoS Configuration 1*/
|
||||
u32 pcfgwqos0_0; /* 0x49c Write QoS Configuration 0*/
|
||||
u32 pcfgwqos1_0; /* 0x4a0 Write QoS Configuration 1*/
|
||||
u8 reserved4a4[0x4b4 - 0x4a4];
|
||||
|
||||
/* PORT 1 */
|
||||
u32 pcfgr_1; /* 0x4b4 Configuration Read*/
|
||||
u32 pcfgw_1; /* 0x4b8 Configuration Write*/
|
||||
u8 reserved4bc[0x540 - 0x4bc];
|
||||
u32 pctrl_1; /* 0x540 Port 2 Control Register */
|
||||
u32 pcfgqos0_1; /* 0x544 Read QoS Configuration 0*/
|
||||
u32 pcfgqos1_1; /* 0x548 Read QoS Configuration 1*/
|
||||
u32 pcfgwqos0_1; /* 0x54c Write QoS Configuration 0*/
|
||||
u32 pcfgwqos1_1; /* 0x550 Write QoS Configuration 1*/
|
||||
};
|
||||
|
||||
/* DDR Physical Interface Control (DDRPHYC) registers*/
|
||||
struct stm32mp1_ddrphy {
|
||||
u32 ridr; /* 0x00 R Revision Identification*/
|
||||
u32 pir; /* 0x04 R/W PHY Initialization*/
|
||||
u32 pgcr; /* 0x08 R/W PHY General Configuration*/
|
||||
u32 pgsr; /* 0x0C PHY General Status*/
|
||||
u32 dllgcr; /* 0x10 R/W DLL General Control*/
|
||||
u32 acdllcr; /* 0x14 R/W AC DLL Control*/
|
||||
u32 ptr0; /* 0x18 R/W PHY Timing 0*/
|
||||
u32 ptr1; /* 0x1C R/W PHY Timing 1*/
|
||||
u32 ptr2; /* 0x20 R/W PHY Timing 2*/
|
||||
u32 aciocr; /* 0x24 AC I/O Configuration*/
|
||||
u32 dxccr; /* 0x28 DATX8 Common Configuration*/
|
||||
u32 dsgcr; /* 0x2C DDR System General Configuration*/
|
||||
u32 dcr; /* 0x30 DRAM Configuration*/
|
||||
u32 dtpr0; /* 0x34 DRAM Timing Parameters0*/
|
||||
u32 dtpr1; /* 0x38 DRAM Timing Parameters1*/
|
||||
u32 dtpr2; /* 0x3C DRAM Timing Parameters2*/
|
||||
u32 mr0; /* 0x40 Mode 0*/
|
||||
u32 mr1; /* 0x44 Mode 1*/
|
||||
u32 mr2; /* 0x48 Mode 2*/
|
||||
u32 mr3; /* 0x4C Mode 3*/
|
||||
u32 odtcr; /* 0x50 ODT Configuration*/
|
||||
u32 dtar; /* 0x54 data training address*/
|
||||
u32 dtdr0; /* 0x58 */
|
||||
u32 dtdr1; /* 0x5c */
|
||||
u8 res1[0x0c0 - 0x060]; /* 0x60 */
|
||||
u32 dcuar; /* 0xc0 Address*/
|
||||
u32 dcudr; /* 0xc4 DCU Data*/
|
||||
u32 dcurr; /* 0xc8 DCU Run*/
|
||||
u32 dculr; /* 0xcc DCU Loop*/
|
||||
u32 dcugcr; /* 0xd0 DCU General Configuration*/
|
||||
u32 dcutpr; /* 0xd4 DCU Timing Parameters */
|
||||
u32 dcusr0; /* 0xd8 DCU Status 0*/
|
||||
u32 dcusr1; /* 0xdc DCU Status 1*/
|
||||
u8 res2[0x100 - 0xe0]; /* 0xe0 */
|
||||
u32 bistrr; /* 0x100 BIST Run*/
|
||||
u32 bistmskr0; /* 0x104 BIST Mask 0*/
|
||||
u32 bistmskr1; /* 0x108 BIST Mask 0*/
|
||||
u32 bistwcr; /* 0x10c BIST Word Count*/
|
||||
u32 bistlsr; /* 0x110 BIST LFSR Seed*/
|
||||
u32 bistar0; /* 0x114 BIST Address 0*/
|
||||
u32 bistar1; /* 0x118 BIST Address 1*/
|
||||
u32 bistar2; /* 0x11c BIST Address 2*/
|
||||
u32 bistupdr; /* 0x120 BIST User Data Pattern*/
|
||||
u32 bistgsr; /* 0x124 BIST General Status*/
|
||||
u32 bistwer; /* 0x128 BIST Word Error*/
|
||||
u32 bistber0; /* 0x12c BIST Bit Error 0*/
|
||||
u32 bistber1; /* 0x130 BIST Bit Error 1*/
|
||||
u32 bistber2; /* 0x134 BIST Bit Error 2*/
|
||||
u32 bistwcsr; /* 0x138 BIST Word Count Status*/
|
||||
u32 bistfwr0; /* 0x13c BIST Fail Word 0*/
|
||||
u32 bistfwr1; /* 0x140 BIST Fail Word 1*/
|
||||
u8 res3[0x178 - 0x144]; /* 0x144 */
|
||||
u32 gpr0; /* 0x178 General Purpose 0 (GPR0)*/
|
||||
u32 gpr1; /* 0x17C General Purpose 1 (GPR1)*/
|
||||
u32 zq0cr0; /* 0x180 zq 0 control 0 */
|
||||
u32 zq0cr1; /* 0x184 zq 0 control 1 */
|
||||
u32 zq0sr0; /* 0x188 zq 0 status 0 */
|
||||
u32 zq0sr1; /* 0x18C zq 0 status 1 */
|
||||
u8 res4[0x1C0 - 0x190]; /* 0x190 */
|
||||
u32 dx0gcr; /* 0x1c0 Byte lane 0 General Configuration*/
|
||||
u32 dx0gsr0; /* 0x1c4 Byte lane 0 General Status 0*/
|
||||
u32 dx0gsr1; /* 0x1c8 Byte lane 0 General Status 1*/
|
||||
u32 dx0dllcr; /* 0x1cc Byte lane 0 DLL Control*/
|
||||
u32 dx0dqtr; /* 0x1d0 Byte lane 0 DQ Timing*/
|
||||
u32 dx0dqstr; /* 0x1d4 Byte lane 0 DQS Timing*/
|
||||
u8 res5[0x200 - 0x1d8]; /* 0x1d8 */
|
||||
u32 dx1gcr; /* 0x200 Byte lane 1 General Configuration*/
|
||||
u32 dx1gsr0; /* 0x204 Byte lane 1 General Status 0*/
|
||||
u32 dx1gsr1; /* 0x208 Byte lane 1 General Status 1*/
|
||||
u32 dx1dllcr; /* 0x20c Byte lane 1 DLL Control*/
|
||||
u32 dx1dqtr; /* 0x210 Byte lane 1 DQ Timing*/
|
||||
u32 dx1dqstr; /* 0x214 Byte lane 1 QS Timing*/
|
||||
u8 res6[0x240 - 0x218]; /* 0x218 */
|
||||
u32 dx2gcr; /* 0x240 Byte lane 2 General Configuration*/
|
||||
u32 dx2gsr0; /* 0x244 Byte lane 2 General Status 0*/
|
||||
u32 dx2gsr1; /* 0x248 Byte lane 2 General Status 1*/
|
||||
u32 dx2dllcr; /* 0x24c Byte lane 2 DLL Control*/
|
||||
u32 dx2dqtr; /* 0x250 Byte lane 2 DQ Timing*/
|
||||
u32 dx2dqstr; /* 0x254 Byte lane 2 QS Timing*/
|
||||
u8 res7[0x280 - 0x258]; /* 0x258 */
|
||||
u32 dx3gcr; /* 0x280 Byte lane 3 General Configuration*/
|
||||
u32 dx3gsr0; /* 0x284 Byte lane 3 General Status 0*/
|
||||
u32 dx3gsr1; /* 0x288 Byte lane 3 General Status 1*/
|
||||
u32 dx3dllcr; /* 0x28c Byte lane 3 DLL Control*/
|
||||
u32 dx3dqtr; /* 0x290 Byte lane 3 DQ Timing*/
|
||||
u32 dx3dqstr; /* 0x294 Byte lane 3 QS Timing*/
|
||||
};
|
||||
|
||||
#define DXN(phy, offset, byte) ((u32)(phy) + (offset) + ((u32)(byte) * 0x40))
|
||||
#define DXNGCR(phy, byte) DXN(phy, 0x1c0, byte)
|
||||
#define DXNDLLCR(phy, byte) DXN(phy, 0x1cc, byte)
|
||||
#define DXNDQTR(phy, byte) DXN(phy, 0x1d0, byte)
|
||||
#define DXNDQSTR(phy, byte) DXN(phy, 0x1d4, byte)
|
||||
|
||||
/* DDRCTRL REGISTERS */
|
||||
#define DDRCTRL_MSTR_DDR3 BIT(0)
|
||||
#define DDRCTRL_MSTR_LPDDR2 BIT(2)
|
||||
#define DDRCTRL_MSTR_LPDDR3 BIT(3)
|
||||
#define DDRCTRL_MSTR_DATA_BUS_WIDTH_MASK GENMASK(13, 12)
|
||||
#define DDRCTRL_MSTR_DATA_BUS_WIDTH_FULL (0 << 12)
|
||||
#define DDRCTRL_MSTR_DATA_BUS_WIDTH_HALF (1 << 12)
|
||||
#define DDRCTRL_MSTR_DATA_BUS_WIDTH_QUARTER (2 << 12)
|
||||
#define DDRCTRL_MSTR_DLL_OFF_MODE BIT(15)
|
||||
|
||||
#define DDRCTRL_STAT_OPERATING_MODE_MASK GENMASK(2, 0)
|
||||
#define DDRCTRL_STAT_OPERATING_MODE_NORMAL 1
|
||||
#define DDRCTRL_STAT_OPERATING_MODE_SR 3
|
||||
#define DDRCTRL_STAT_SELFREF_TYPE_MASK GENMASK(5, 4)
|
||||
#define DDRCTRL_STAT_SELFREF_TYPE_ASR (3 << 4)
|
||||
#define DDRCTRL_STAT_SELFREF_TYPE_SR (2 << 4)
|
||||
|
||||
#define DDRCTRL_MRCTRL0_MR_TYPE_WRITE 0
|
||||
/* only one rank supported */
|
||||
#define DDRCTRL_MRCTRL0_MR_RANK_SHIFT 4
|
||||
#define DDRCTRL_MRCTRL0_MR_RANK_ALL \
|
||||
(0x1 << DDRCTRL_MRCTRL0_MR_RANK_SHIFT)
|
||||
#define DDRCTRL_MRCTRL0_MR_ADDR_SHIFT 12
|
||||
#define DDRCTRL_MRCTRL0_MR_ADDR_MASK GENMASK(15, 12)
|
||||
#define DDRCTRL_MRCTRL0_MR_WR BIT(31)
|
||||
|
||||
#define DDRCTRL_MRSTAT_MR_WR_BUSY BIT(0)
|
||||
|
||||
#define DDRCTRL_PWRCTL_POWERDOWN_EN BIT(1)
|
||||
#define DDRCTRL_PWRCTL_SELFREF_SW BIT(5)
|
||||
|
||||
#define DDRCTRL_RFSHCTL3_DIS_AUTO_REFRESH BIT(0)
|
||||
|
||||
#define DDRCTRL_RFSHTMG_T_RFC_NOM_X1_X32_MASK GENMASK(27, 16)
|
||||
#define DDRCTRL_RFSHTMG_T_RFC_NOM_X1_X32_SHIFT 16
|
||||
|
||||
#define DDRCTRL_INIT0_SKIP_DRAM_INIT_MASK (0xC0000000)
|
||||
#define DDRCTRL_INIT0_SKIP_DRAM_INIT_NORMAL (BIT(30))
|
||||
|
||||
#define DDRCTRL_DFIMISC_DFI_INIT_COMPLETE_EN BIT(0)
|
||||
|
||||
#define DDRCTRL_DBG1_DIS_HIF BIT(1)
|
||||
|
||||
#define DDRCTRL_DBGCAM_WR_DATA_PIPELINE_EMPTY BIT(29)
|
||||
#define DDRCTRL_DBGCAM_RD_DATA_PIPELINE_EMPTY BIT(28)
|
||||
#define DDRCTRL_DBGCAM_DBG_WR_Q_EMPTY BIT(26)
|
||||
#define DDRCTRL_DBGCAM_DBG_LPR_Q_DEPTH GENMASK(12, 8)
|
||||
#define DDRCTRL_DBGCAM_DBG_HPR_Q_DEPTH GENMASK(4, 0)
|
||||
#define DDRCTRL_DBGCAM_DATA_PIPELINE_EMPTY \
|
||||
(DDRCTRL_DBGCAM_WR_DATA_PIPELINE_EMPTY | \
|
||||
DDRCTRL_DBGCAM_RD_DATA_PIPELINE_EMPTY)
|
||||
#define DDRCTRL_DBGCAM_DBG_Q_DEPTH \
|
||||
(DDRCTRL_DBGCAM_DBG_WR_Q_EMPTY | \
|
||||
DDRCTRL_DBGCAM_DBG_LPR_Q_DEPTH | \
|
||||
DDRCTRL_DBGCAM_DBG_HPR_Q_DEPTH)
|
||||
|
||||
#define DDRCTRL_DBGCMD_RANK0_REFRESH BIT(0)
|
||||
|
||||
#define DDRCTRL_DBGSTAT_RANK0_REFRESH_BUSY BIT(0)
|
||||
|
||||
#define DDRCTRL_SWCTL_SW_DONE BIT(0)
|
||||
|
||||
#define DDRCTRL_SWSTAT_SW_DONE_ACK BIT(0)
|
||||
|
||||
#define DDRCTRL_PCTRL_N_PORT_EN BIT(0)
|
||||
|
||||
/* DDRPHYC registers */
|
||||
#define DDRPHYC_PIR_INIT BIT(0)
|
||||
#define DDRPHYC_PIR_DLLSRST BIT(1)
|
||||
#define DDRPHYC_PIR_DLLLOCK BIT(2)
|
||||
#define DDRPHYC_PIR_ZCAL BIT(3)
|
||||
#define DDRPHYC_PIR_ITMSRST BIT(4)
|
||||
#define DDRPHYC_PIR_DRAMRST BIT(5)
|
||||
#define DDRPHYC_PIR_DRAMINIT BIT(6)
|
||||
#define DDRPHYC_PIR_QSTRN BIT(7)
|
||||
#define DDRPHYC_PIR_ICPC BIT(16)
|
||||
#define DDRPHYC_PIR_ZCALBYP BIT(30)
|
||||
#define DDRPHYC_PIR_INITSTEPS_MASK GENMASK(31, 7)
|
||||
|
||||
#define DDRPHYC_PGCR_DFTCMP BIT(2)
|
||||
#define DDRPHYC_PGCR_PDDISDX BIT(24)
|
||||
#define DDRPHYC_PGCR_RFSHDT_MASK GENMASK(28, 25)
|
||||
|
||||
#define DDRPHYC_PGSR_IDONE BIT(0)
|
||||
#define DDRPHYC_PGSR_DTERR BIT(5)
|
||||
#define DDRPHYC_PGSR_DTIERR BIT(6)
|
||||
#define DDRPHYC_PGSR_DFTERR BIT(7)
|
||||
#define DDRPHYC_PGSR_RVERR BIT(8)
|
||||
#define DDRPHYC_PGSR_RVEIRR BIT(9)
|
||||
|
||||
#define DDRPHYC_DLLGCR_BPS200 BIT(23)
|
||||
|
||||
#define DDRPHYC_ACDLLCR_DLLDIS BIT(31)
|
||||
|
||||
#define DDRPHYC_ZQ0CRN_ZDATA_MASK GENMASK(27, 0)
|
||||
#define DDRPHYC_ZQ0CRN_ZDATA_SHIFT 0
|
||||
#define DDRPHYC_ZQ0CRN_ZDEN BIT(28)
|
||||
|
||||
#define DDRPHYC_DXNGCR_DXEN BIT(0)
|
||||
|
||||
#define DDRPHYC_DXNDLLCR_DLLSRST BIT(30)
|
||||
#define DDRPHYC_DXNDLLCR_DLLDIS BIT(31)
|
||||
#define DDRPHYC_DXNDLLCR_SDPHASE_MASK GENMASK(17, 14)
|
||||
#define DDRPHYC_DXNDLLCR_SDPHASE_SHIFT 14
|
||||
|
||||
#define DDRPHYC_DXNDQTR_DQDLY_SHIFT(bit) (4 * (bit))
|
||||
#define DDRPHYC_DXNDQTR_DQDLY_MASK GENMASK(3, 0)
|
||||
#define DDRPHYC_DXNDQTR_DQDLY_LOW_MASK GENMASK(1, 0)
|
||||
#define DDRPHYC_DXNDQTR_DQDLY_HIGH_MASK GENMASK(3, 2)
|
||||
|
||||
#define DDRPHYC_DXNDQSTR_DQSDLY_MASK GENMASK(22, 20)
|
||||
#define DDRPHYC_DXNDQSTR_DQSDLY_SHIFT 20
|
||||
#define DDRPHYC_DXNDQSTR_DQSNDLY_MASK GENMASK(25, 23)
|
||||
#define DDRPHYC_DXNDQSTR_DQSNDLY_SHIFT 23
|
||||
#define DDRPHYC_DXNDQSTR_R0DGSL_MASK GENMASK(2, 0)
|
||||
#define DDRPHYC_DXNDQSTR_R0DGSL_SHIFT 0
|
||||
#define DDRPHYC_DXNDQSTR_R0DGPS_MASK GENMASK(13, 12)
|
||||
#define DDRPHYC_DXNDQSTR_R0DGPS_SHIFT 12
|
||||
|
||||
#define DDRPHYC_BISTRR_BDXSEL_MASK GENMASK(22, 19)
|
||||
#define DDRPHYC_BISTRR_BDXSEL_SHIFT 19
|
||||
|
||||
#define DDRPHYC_BISTGSR_BDDONE BIT(0)
|
||||
#define DDRPHYC_BISTGSR_BDXERR BIT(2)
|
||||
|
||||
#define DDRPHYC_BISTWCSR_DXWCNT_SHIFT 16
|
||||
|
||||
/* PWR registers */
|
||||
#define PWR_CR3 0x00C
|
||||
#define PWR_CR3_DDRSRDIS BIT(11)
|
||||
#define PWR_CR3_DDRRETEN BIT(12)
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,483 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
|
||||
/*
|
||||
* Copyright (C) 2019, STMicroelectronics - All Rights Reserved
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <console.h>
|
||||
#include <cli.h>
|
||||
#include <clk.h>
|
||||
#include <malloc.h>
|
||||
#include <ram.h>
|
||||
#include <reset.h>
|
||||
#include "stm32mp1_ddr.h"
|
||||
#include "stm32mp1_tests.h"
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
enum ddr_command {
|
||||
DDR_CMD_HELP,
|
||||
DDR_CMD_INFO,
|
||||
DDR_CMD_FREQ,
|
||||
DDR_CMD_RESET,
|
||||
DDR_CMD_PARAM,
|
||||
DDR_CMD_PRINT,
|
||||
DDR_CMD_EDIT,
|
||||
DDR_CMD_STEP,
|
||||
DDR_CMD_NEXT,
|
||||
DDR_CMD_GO,
|
||||
DDR_CMD_TEST,
|
||||
DDR_CMD_TUNING,
|
||||
DDR_CMD_UNKNOWN,
|
||||
};
|
||||
|
||||
const char *step_str[] = {
|
||||
[STEP_DDR_RESET] = "DDR_RESET",
|
||||
[STEP_CTL_INIT] = "DDR_CTRL_INIT_DONE",
|
||||
[STEP_PHY_INIT] = "DDR PHY_INIT_DONE",
|
||||
[STEP_DDR_READY] = "DDR_READY",
|
||||
[STEP_RUN] = "RUN"
|
||||
};
|
||||
|
||||
enum ddr_command stm32mp1_get_command(char *cmd, int argc)
|
||||
{
|
||||
const char *cmd_string[DDR_CMD_UNKNOWN] = {
|
||||
[DDR_CMD_HELP] = "help",
|
||||
[DDR_CMD_INFO] = "info",
|
||||
[DDR_CMD_FREQ] = "freq",
|
||||
[DDR_CMD_RESET] = "reset",
|
||||
[DDR_CMD_PARAM] = "param",
|
||||
[DDR_CMD_PRINT] = "print",
|
||||
[DDR_CMD_EDIT] = "edit",
|
||||
[DDR_CMD_STEP] = "step",
|
||||
[DDR_CMD_NEXT] = "next",
|
||||
[DDR_CMD_GO] = "go",
|
||||
#ifdef CONFIG_STM32MP1_DDR_TESTS
|
||||
[DDR_CMD_TEST] = "test",
|
||||
#endif
|
||||
#ifdef CONFIG_STM32MP1_DDR_TUNING
|
||||
[DDR_CMD_TUNING] = "tuning",
|
||||
#endif
|
||||
};
|
||||
/* min and max number of argument */
|
||||
const char cmd_arg[DDR_CMD_UNKNOWN][2] = {
|
||||
[DDR_CMD_HELP] = { 0, 0 },
|
||||
[DDR_CMD_INFO] = { 0, 255 },
|
||||
[DDR_CMD_FREQ] = { 0, 1 },
|
||||
[DDR_CMD_RESET] = { 0, 0 },
|
||||
[DDR_CMD_PARAM] = { 0, 2 },
|
||||
[DDR_CMD_PRINT] = { 0, 1 },
|
||||
[DDR_CMD_EDIT] = { 2, 2 },
|
||||
[DDR_CMD_STEP] = { 0, 1 },
|
||||
[DDR_CMD_NEXT] = { 0, 0 },
|
||||
[DDR_CMD_GO] = { 0, 0 },
|
||||
#ifdef CONFIG_STM32MP1_DDR_TESTS
|
||||
[DDR_CMD_TEST] = { 0, 255 },
|
||||
#endif
|
||||
#ifdef CONFIG_STM32MP1_DDR_TUNING
|
||||
[DDR_CMD_TUNING] = { 0, 255 },
|
||||
#endif
|
||||
};
|
||||
int i;
|
||||
|
||||
for (i = 0; i < DDR_CMD_UNKNOWN; i++)
|
||||
if (!strcmp(cmd, cmd_string[i])) {
|
||||
if (argc - 1 < cmd_arg[i][0]) {
|
||||
printf("no enought argument (min=%d)\n",
|
||||
cmd_arg[i][0]);
|
||||
return DDR_CMD_UNKNOWN;
|
||||
} else if (argc - 1 > cmd_arg[i][1]) {
|
||||
printf("too many argument (max=%d)\n",
|
||||
cmd_arg[i][1]);
|
||||
return DDR_CMD_UNKNOWN;
|
||||
} else {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
printf("unknown command %s\n", cmd);
|
||||
return DDR_CMD_UNKNOWN;
|
||||
}
|
||||
|
||||
static void stm32mp1_do_usage(void)
|
||||
{
|
||||
const char *usage = {
|
||||
"commands:\n\n"
|
||||
"help displays help\n"
|
||||
"info displays DDR information\n"
|
||||
"info <param> <val> changes DDR information\n"
|
||||
" with <param> = step, name, size or speed\n"
|
||||
"freq displays the DDR PHY frequency in kHz\n"
|
||||
"freq <freq> changes the DDR PHY frequency\n"
|
||||
"param [type|reg] prints input parameters\n"
|
||||
"param <reg> <val> edits parameters in step 0\n"
|
||||
"print [type|reg] dumps registers\n"
|
||||
"edit <reg> <val> modifies one register\n"
|
||||
"step lists the available step\n"
|
||||
"step <n> go to the step <n>\n"
|
||||
"next goes to the next step\n"
|
||||
"go continues the U-Boot SPL execution\n"
|
||||
"reset reboots machine\n"
|
||||
#ifdef CONFIG_STM32MP1_DDR_TESTS
|
||||
"test [help] | <n> [...] lists (with help) or executes test <n>\n"
|
||||
#endif
|
||||
#ifdef CONFIG_STM32MP1_DDR_TUNING
|
||||
"tuning [help] | <n> [...] lists (with help) or execute tuning <n>\n"
|
||||
#endif
|
||||
"\nwith for [type|reg]:\n"
|
||||
" all registers if absent\n"
|
||||
" <type> = ctl, phy\n"
|
||||
" or one category (static, timing, map, perf, cal, dyn)\n"
|
||||
" <reg> = name of the register\n"
|
||||
};
|
||||
|
||||
puts(usage);
|
||||
}
|
||||
|
||||
static bool stm32mp1_check_step(enum stm32mp1_ddr_interact_step step,
|
||||
enum stm32mp1_ddr_interact_step expected)
|
||||
{
|
||||
if (step != expected) {
|
||||
printf("invalid step %d:%s expecting %d:%s\n",
|
||||
step, step_str[step],
|
||||
expected,
|
||||
step_str[expected]);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static void stm32mp1_do_info(struct ddr_info *priv,
|
||||
struct stm32mp1_ddr_config *config,
|
||||
enum stm32mp1_ddr_interact_step step,
|
||||
int argc, char * const argv[])
|
||||
{
|
||||
unsigned long value;
|
||||
static char *ddr_name;
|
||||
|
||||
if (argc == 1) {
|
||||
printf("step = %d : %s\n", step, step_str[step]);
|
||||
printf("name = %s\n", config->info.name);
|
||||
printf("size = 0x%x\n", config->info.size);
|
||||
printf("speed = %d kHz\n", config->info.speed);
|
||||
return;
|
||||
}
|
||||
|
||||
if (argc < 3) {
|
||||
printf("no enought parameter\n");
|
||||
return;
|
||||
}
|
||||
if (!strcmp(argv[1], "name")) {
|
||||
u32 i, name_len = 0;
|
||||
|
||||
for (i = 2; i < argc; i++)
|
||||
name_len += strlen(argv[i]) + 1;
|
||||
if (ddr_name)
|
||||
free(ddr_name);
|
||||
ddr_name = malloc(name_len);
|
||||
config->info.name = ddr_name;
|
||||
if (!ddr_name) {
|
||||
printf("alloc error, length %d\n", name_len);
|
||||
return;
|
||||
}
|
||||
strcpy(ddr_name, argv[2]);
|
||||
for (i = 3; i < argc; i++) {
|
||||
strcat(ddr_name, " ");
|
||||
strcat(ddr_name, argv[i]);
|
||||
}
|
||||
printf("name = %s\n", ddr_name);
|
||||
return;
|
||||
}
|
||||
if (!strcmp(argv[1], "size")) {
|
||||
if (strict_strtoul(argv[2], 16, &value) < 0) {
|
||||
printf("invalid value %s\n", argv[2]);
|
||||
} else {
|
||||
config->info.size = value;
|
||||
printf("size = 0x%x\n", config->info.size);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (!strcmp(argv[1], "speed")) {
|
||||
if (strict_strtoul(argv[2], 10, &value) < 0) {
|
||||
printf("invalid value %s\n", argv[2]);
|
||||
} else {
|
||||
config->info.speed = value;
|
||||
printf("speed = %d kHz\n", config->info.speed);
|
||||
value = clk_get_rate(&priv->clk);
|
||||
printf("DDRPHY = %ld kHz\n", value / 1000);
|
||||
}
|
||||
return;
|
||||
}
|
||||
printf("argument %s invalid\n", argv[1]);
|
||||
}
|
||||
|
||||
static bool stm32mp1_do_freq(struct ddr_info *priv,
|
||||
int argc, char * const argv[])
|
||||
{
|
||||
unsigned long ddrphy_clk;
|
||||
|
||||
if (argc == 2) {
|
||||
if (strict_strtoul(argv[1], 0, &ddrphy_clk) < 0) {
|
||||
printf("invalid argument %s", argv[1]);
|
||||
return false;
|
||||
}
|
||||
if (clk_set_rate(&priv->clk, ddrphy_clk * 1000)) {
|
||||
printf("ERROR: update failed!\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
ddrphy_clk = clk_get_rate(&priv->clk);
|
||||
printf("DDRPHY = %ld kHz\n", ddrphy_clk / 1000);
|
||||
if (argc == 2)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
static void stm32mp1_do_param(enum stm32mp1_ddr_interact_step step,
|
||||
const struct stm32mp1_ddr_config *config,
|
||||
int argc, char * const argv[])
|
||||
{
|
||||
switch (argc) {
|
||||
case 1:
|
||||
stm32mp1_dump_param(config, NULL);
|
||||
break;
|
||||
case 2:
|
||||
if (stm32mp1_dump_param(config, argv[1]))
|
||||
printf("invalid argument %s\n",
|
||||
argv[1]);
|
||||
break;
|
||||
case 3:
|
||||
if (!stm32mp1_check_step(step, STEP_DDR_RESET))
|
||||
return;
|
||||
stm32mp1_edit_param(config, argv[1], argv[2]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void stm32mp1_do_print(struct ddr_info *priv,
|
||||
int argc, char * const argv[])
|
||||
{
|
||||
switch (argc) {
|
||||
case 1:
|
||||
stm32mp1_dump_reg(priv, NULL);
|
||||
break;
|
||||
case 2:
|
||||
if (stm32mp1_dump_reg(priv, argv[1]))
|
||||
printf("invalid argument %s\n",
|
||||
argv[1]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int stm32mp1_do_step(enum stm32mp1_ddr_interact_step step,
|
||||
int argc, char * const argv[])
|
||||
{
|
||||
int i;
|
||||
unsigned long value;
|
||||
|
||||
switch (argc) {
|
||||
case 1:
|
||||
for (i = 0; i < ARRAY_SIZE(step_str); i++)
|
||||
printf("%d:%s\n", i, step_str[i]);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
if ((strict_strtoul(argv[1], 0,
|
||||
&value) < 0) ||
|
||||
value >= ARRAY_SIZE(step_str)) {
|
||||
printf("invalid argument %s\n",
|
||||
argv[1]);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (value != STEP_DDR_RESET &&
|
||||
value <= step) {
|
||||
printf("invalid target %d:%s, current step is %d:%s\n",
|
||||
(int)value, step_str[value],
|
||||
step, step_str[step]);
|
||||
goto end;
|
||||
}
|
||||
printf("step to %d:%s\n",
|
||||
(int)value, step_str[value]);
|
||||
return (int)value;
|
||||
};
|
||||
|
||||
end:
|
||||
return step;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_STM32MP1_DDR_TESTS) || defined(CONFIG_STM32MP1_DDR_TUNING)
|
||||
static const char * const s_result[] = {
|
||||
[TEST_PASSED] = "Pass",
|
||||
[TEST_FAILED] = "Failed",
|
||||
[TEST_ERROR] = "Error"
|
||||
};
|
||||
|
||||
static void stm32mp1_ddr_subcmd(struct ddr_info *priv,
|
||||
int argc, char *argv[],
|
||||
const struct test_desc array[],
|
||||
const int array_nb)
|
||||
{
|
||||
int i;
|
||||
unsigned long value;
|
||||
int result;
|
||||
char string[50] = "";
|
||||
|
||||
if (argc == 1) {
|
||||
printf("%s:%d\n", argv[0], array_nb);
|
||||
for (i = 0; i < array_nb; i++)
|
||||
printf("%d:%s:%s\n",
|
||||
i, array[i].name, array[i].usage);
|
||||
return;
|
||||
}
|
||||
if (argc > 1 && !strcmp(argv[1], "help")) {
|
||||
printf("%s:%d\n", argv[0], array_nb);
|
||||
for (i = 0; i < array_nb; i++)
|
||||
printf("%d:%s:%s:%s\n", i,
|
||||
array[i].name, array[i].usage, array[i].help);
|
||||
return;
|
||||
}
|
||||
|
||||
if ((strict_strtoul(argv[1], 0, &value) < 0) ||
|
||||
value >= array_nb) {
|
||||
sprintf(string, "invalid argument %s",
|
||||
argv[1]);
|
||||
result = TEST_FAILED;
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (argc > (array[value].max_args + 2)) {
|
||||
sprintf(string, "invalid nb of args %d, max %d",
|
||||
argc - 2, array[value].max_args);
|
||||
result = TEST_FAILED;
|
||||
goto end;
|
||||
}
|
||||
|
||||
printf("execute %d:%s\n", (int)value, array[value].name);
|
||||
clear_ctrlc();
|
||||
result = array[value].fct(priv->ctl, priv->phy,
|
||||
string, argc - 2, &argv[2]);
|
||||
|
||||
end:
|
||||
printf("Result: %s [%s]\n", s_result[result], string);
|
||||
}
|
||||
#endif
|
||||
|
||||
bool stm32mp1_ddr_interactive(void *priv,
|
||||
enum stm32mp1_ddr_interact_step step,
|
||||
const struct stm32mp1_ddr_config *config)
|
||||
{
|
||||
const char *prompt = "DDR>";
|
||||
char buffer[CONFIG_SYS_CBSIZE];
|
||||
char *argv[CONFIG_SYS_MAXARGS + 1]; /* NULL terminated */
|
||||
int argc;
|
||||
static int next_step = -1;
|
||||
|
||||
if (next_step < 0 && step == STEP_DDR_RESET) {
|
||||
#ifdef CONFIG_STM32MP1_DDR_INTERACTIVE_FORCE
|
||||
gd->flags &= ~(GD_FLG_SILENT |
|
||||
GD_FLG_DISABLE_CONSOLE);
|
||||
next_step = STEP_DDR_RESET;
|
||||
#else
|
||||
unsigned long start = get_timer(0);
|
||||
|
||||
while (1) {
|
||||
if (tstc() && (getc() == 'd')) {
|
||||
next_step = STEP_DDR_RESET;
|
||||
break;
|
||||
}
|
||||
if (get_timer(start) > 100)
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
debug("** step %d ** %s / %d\n", step, step_str[step], next_step);
|
||||
|
||||
if (next_step < 0)
|
||||
return false;
|
||||
|
||||
if (step < 0 || step > ARRAY_SIZE(step_str)) {
|
||||
printf("** step %d ** INVALID\n", step);
|
||||
return false;
|
||||
}
|
||||
|
||||
printf("%d:%s\n", step, step_str[step]);
|
||||
printf("%s\n", prompt);
|
||||
|
||||
if (next_step > step)
|
||||
return false;
|
||||
|
||||
while (next_step == step) {
|
||||
cli_readline_into_buffer(prompt, buffer, 0);
|
||||
argc = cli_simple_parse_line(buffer, argv);
|
||||
if (!argc)
|
||||
continue;
|
||||
|
||||
switch (stm32mp1_get_command(argv[0], argc)) {
|
||||
case DDR_CMD_HELP:
|
||||
stm32mp1_do_usage();
|
||||
break;
|
||||
|
||||
case DDR_CMD_INFO:
|
||||
stm32mp1_do_info(priv,
|
||||
(struct stm32mp1_ddr_config *)config,
|
||||
step, argc, argv);
|
||||
break;
|
||||
|
||||
case DDR_CMD_FREQ:
|
||||
if (stm32mp1_do_freq(priv, argc, argv))
|
||||
next_step = STEP_DDR_RESET;
|
||||
break;
|
||||
|
||||
case DDR_CMD_RESET:
|
||||
do_reset(NULL, 0, 0, NULL);
|
||||
break;
|
||||
|
||||
case DDR_CMD_PARAM:
|
||||
stm32mp1_do_param(step, config, argc, argv);
|
||||
break;
|
||||
|
||||
case DDR_CMD_PRINT:
|
||||
stm32mp1_do_print(priv, argc, argv);
|
||||
break;
|
||||
|
||||
case DDR_CMD_EDIT:
|
||||
stm32mp1_edit_reg(priv, argv[1], argv[2]);
|
||||
break;
|
||||
|
||||
case DDR_CMD_GO:
|
||||
next_step = STEP_RUN;
|
||||
break;
|
||||
|
||||
case DDR_CMD_NEXT:
|
||||
next_step = step + 1;
|
||||
break;
|
||||
|
||||
case DDR_CMD_STEP:
|
||||
next_step = stm32mp1_do_step(step, argc, argv);
|
||||
break;
|
||||
|
||||
#ifdef CONFIG_STM32MP1_DDR_TESTS
|
||||
case DDR_CMD_TEST:
|
||||
if (!stm32mp1_check_step(step, STEP_DDR_READY))
|
||||
continue;
|
||||
stm32mp1_ddr_subcmd(priv, argc, argv, test, test_nb);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_STM32MP1_DDR_TUNING
|
||||
case DDR_CMD_TUNING:
|
||||
if (!stm32mp1_check_step(step, STEP_DDR_READY))
|
||||
continue;
|
||||
stm32mp1_ddr_subcmd(priv, argc, argv,
|
||||
tuning, tuning_nb);
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return next_step == STEP_DDR_RESET;
|
||||
}
|
||||
@@ -0,0 +1,196 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
|
||||
/*
|
||||
* Copyright (C) 2018, STMicroelectronics - All Rights Reserved
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <clk.h>
|
||||
#include <dm.h>
|
||||
#include <ram.h>
|
||||
#include <regmap.h>
|
||||
#include <syscon.h>
|
||||
#include <asm/io.h>
|
||||
#include "stm32mp1_ddr.h"
|
||||
|
||||
static const char *const clkname[] = {
|
||||
"ddrc1",
|
||||
"ddrc2",
|
||||
"ddrcapb",
|
||||
"ddrphycapb",
|
||||
"ddrphyc" /* LAST clock => used for get_rate() */
|
||||
};
|
||||
|
||||
int stm32mp1_ddr_clk_enable(struct ddr_info *priv, uint32_t mem_speed)
|
||||
{
|
||||
unsigned long ddrphy_clk;
|
||||
unsigned long ddr_clk;
|
||||
struct clk clk;
|
||||
int ret;
|
||||
unsigned int idx;
|
||||
|
||||
for (idx = 0; idx < ARRAY_SIZE(clkname); idx++) {
|
||||
ret = clk_get_by_name(priv->dev, clkname[idx], &clk);
|
||||
|
||||
if (!ret)
|
||||
ret = clk_enable(&clk);
|
||||
|
||||
if (ret) {
|
||||
printf("error for %s : %d\n", clkname[idx], ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
priv->clk = clk;
|
||||
ddrphy_clk = clk_get_rate(&priv->clk);
|
||||
|
||||
debug("DDR: mem_speed (%d kHz), RCC %d kHz\n",
|
||||
mem_speed, (u32)(ddrphy_clk / 1000));
|
||||
/* max 10% frequency delta */
|
||||
ddr_clk = abs(ddrphy_clk - mem_speed * 1000);
|
||||
if (ddr_clk > (mem_speed * 100)) {
|
||||
pr_err("DDR expected freq %d kHz, current is %d kHz\n",
|
||||
mem_speed, (u32)(ddrphy_clk / 1000));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static __maybe_unused int stm32mp1_ddr_setup(struct udevice *dev)
|
||||
{
|
||||
struct ddr_info *priv = dev_get_priv(dev);
|
||||
int ret;
|
||||
unsigned int idx;
|
||||
struct clk axidcg;
|
||||
struct stm32mp1_ddr_config config;
|
||||
|
||||
#define PARAM(x, y) \
|
||||
{ x,\
|
||||
offsetof(struct stm32mp1_ddr_config, y),\
|
||||
sizeof(config.y) / sizeof(u32)}
|
||||
|
||||
#define CTL_PARAM(x) PARAM("st,ctl-"#x, c_##x)
|
||||
#define PHY_PARAM(x) PARAM("st,phy-"#x, p_##x)
|
||||
|
||||
const struct {
|
||||
const char *name; /* name in DT */
|
||||
const u32 offset; /* offset in config struct */
|
||||
const u32 size; /* size of parameters */
|
||||
} param[] = {
|
||||
CTL_PARAM(reg),
|
||||
CTL_PARAM(timing),
|
||||
CTL_PARAM(map),
|
||||
CTL_PARAM(perf),
|
||||
PHY_PARAM(reg),
|
||||
PHY_PARAM(timing),
|
||||
PHY_PARAM(cal)
|
||||
};
|
||||
|
||||
config.info.speed = dev_read_u32_default(dev, "st,mem-speed", 0);
|
||||
config.info.size = dev_read_u32_default(dev, "st,mem-size", 0);
|
||||
config.info.name = dev_read_string(dev, "st,mem-name");
|
||||
if (!config.info.name) {
|
||||
debug("%s: no st,mem-name\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
printf("RAM: %s\n", config.info.name);
|
||||
|
||||
for (idx = 0; idx < ARRAY_SIZE(param); idx++) {
|
||||
ret = dev_read_u32_array(dev, param[idx].name,
|
||||
(void *)((u32)&config +
|
||||
param[idx].offset),
|
||||
param[idx].size);
|
||||
debug("%s: %s[0x%x] = %d\n", __func__,
|
||||
param[idx].name, param[idx].size, ret);
|
||||
if (ret) {
|
||||
pr_err("%s: Cannot read %s, error=%d\n",
|
||||
__func__, param[idx].name, ret);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
ret = clk_get_by_name(dev, "axidcg", &axidcg);
|
||||
if (ret) {
|
||||
debug("%s: Cannot found axidcg\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
clk_disable(&axidcg); /* disable clock gating during init */
|
||||
|
||||
stm32mp1_ddr_init(priv, &config);
|
||||
|
||||
clk_enable(&axidcg); /* enable clock gating */
|
||||
|
||||
/* check size */
|
||||
debug("%s : get_ram_size(%x, %x)\n", __func__,
|
||||
(u32)priv->info.base, (u32)STM32_DDR_SIZE);
|
||||
|
||||
priv->info.size = get_ram_size((long *)priv->info.base,
|
||||
STM32_DDR_SIZE);
|
||||
|
||||
debug("%s : %x\n", __func__, (u32)priv->info.size);
|
||||
|
||||
/* check memory access for all memory */
|
||||
if (config.info.size != priv->info.size) {
|
||||
printf("DDR invalid size : 0x%x, expected 0x%x\n",
|
||||
priv->info.size, config.info.size);
|
||||
return -EINVAL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int stm32mp1_ddr_probe(struct udevice *dev)
|
||||
{
|
||||
struct ddr_info *priv = dev_get_priv(dev);
|
||||
struct regmap *map;
|
||||
int ret;
|
||||
|
||||
debug("STM32MP1 DDR probe\n");
|
||||
priv->dev = dev;
|
||||
|
||||
ret = regmap_init_mem(dev_ofnode(dev), &map);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
priv->ctl = regmap_get_range(map, 0);
|
||||
priv->phy = regmap_get_range(map, 1);
|
||||
|
||||
priv->rcc = STM32_RCC_BASE;
|
||||
|
||||
priv->info.base = STM32_DDR_BASE;
|
||||
|
||||
#if !defined(CONFIG_STM32MP1_TRUSTED) && \
|
||||
(!defined(CONFIG_SPL) || defined(CONFIG_SPL_BUILD))
|
||||
priv->info.size = 0;
|
||||
return stm32mp1_ddr_setup(dev);
|
||||
#else
|
||||
priv->info.size = dev_read_u32_default(dev, "st,mem-size", 0);
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
static int stm32mp1_ddr_get_info(struct udevice *dev, struct ram_info *info)
|
||||
{
|
||||
struct ddr_info *priv = dev_get_priv(dev);
|
||||
|
||||
*info = priv->info;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct ram_ops stm32mp1_ddr_ops = {
|
||||
.get_info = stm32mp1_ddr_get_info,
|
||||
};
|
||||
|
||||
static const struct udevice_id stm32mp1_ddr_ids[] = {
|
||||
{ .compatible = "st,stm32mp1-ddr" },
|
||||
{ }
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(ddr_stm32mp1) = {
|
||||
.name = "stm32mp1_ddr",
|
||||
.id = UCLASS_RAM,
|
||||
.of_match = stm32mp1_ddr_ids,
|
||||
.ops = &stm32mp1_ddr_ops,
|
||||
.probe = stm32mp1_ddr_probe,
|
||||
.priv_auto_alloc_size = sizeof(struct ddr_info),
|
||||
};
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,34 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */
|
||||
/*
|
||||
* Copyright (C) 2019, STMicroelectronics - All Rights Reserved
|
||||
*/
|
||||
|
||||
#ifndef _RAM_STM32MP1_TESTS_H_
|
||||
#define _RAM_STM32MP1_TESTS_H_
|
||||
|
||||
#include "stm32mp1_ddr_regs.h"
|
||||
|
||||
enum test_result {
|
||||
TEST_PASSED,
|
||||
TEST_FAILED,
|
||||
TEST_ERROR
|
||||
};
|
||||
|
||||
struct test_desc {
|
||||
enum test_result (*fct)(struct stm32mp1_ddrctl *ctl,
|
||||
struct stm32mp1_ddrphy *phy,
|
||||
char *string,
|
||||
int argc, char *argv[]);
|
||||
const char *name;
|
||||
const char *usage;
|
||||
const char *help;
|
||||
u8 max_args;
|
||||
};
|
||||
|
||||
extern const struct test_desc test[];
|
||||
extern const int test_nb;
|
||||
|
||||
extern const struct test_desc tuning[];
|
||||
extern const int tuning_nb;
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user