ram: k3-ddrss: Introduce common driver with J7 SoC support

Introduce a new version of the ddr driver which has the ability to
support different variations of the controller. Also introduce support
for the 32bit variation of the controller which is what was already
supported by the previous version used for J721e and J7200.

Signed-off-by: Dave Gerlach <d-gerlach@ti.com>
This commit is contained in:
Dave Gerlach 2021-05-11 10:22:11 -05:00 committed by Lokesh Vutla
parent db2438131d
commit a8c13c777e
27 changed files with 3619 additions and 3793 deletions

View File

@ -0,0 +1,91 @@
/* SPDX-License-Identifier: BSD-3-Clause */
/*
* Cadence DDR Driver
*
* Copyright (C) 2012-2021 Cadence Design Systems, Inc.
* Copyright (C) 2018-2021 Texas Instruments Incorporated - https://www.ti.com/
*/
#ifndef LPDDR4_32BIT_IF_H
#define LPDDR4_32BIT_IF_H
#include <linux/types.h>
#define LPDDR4_INTR_MAX_CS (2U)
#define LPDDR4_INTR_CTL_REG_COUNT (459U)
#define LPDDR4_INTR_PHY_INDEP_REG_COUNT (300U)
#define LPDDR4_INTR_PHY_REG_COUNT (1423U)
typedef enum {
LPDDR4_INTR_RESET_DONE = 0U,
LPDDR4_INTR_BUS_ACCESS_ERROR = 1U,
LPDDR4_INTR_MULTIPLE_BUS_ACCESS_ERROR = 2U,
LPDDR4_INTR_ECC_MULTIPLE_CORR_ERROR = 3U,
LPDDR4_INTR_ECC_MULTIPLE_UNCORR_ERROR = 4U,
LPDDR4_INTR_ECC_WRITEBACK_EXEC_ERROR = 5U,
LPDDR4_INTR_ECC_SCRUB_DONE = 6U,
LPDDR4_INTR_ECC_SCRUB_ERROR = 7U,
LPDDR4_INTR_PORT_COMMAND_ERROR = 8U,
LPDDR4_INTR_MC_INIT_DONE = 9U,
LPDDR4_INTR_LP_DONE = 10U,
LPDDR4_INTR_BIST_DONE = 11U,
LPDDR4_INTR_WRAP_ERROR = 12U,
LPDDR4_INTR_INVALID_BURST_ERROR = 13U,
LPDDR4_INTR_RDLVL_ERROR = 14U,
LPDDR4_INTR_RDLVL_GATE_ERROR = 15U,
LPDDR4_INTR_WRLVL_ERROR = 16U,
LPDDR4_INTR_CA_TRAINING_ERROR = 17U,
LPDDR4_INTR_DFI_UPDATE_ERROR = 18U,
LPDDR4_INTR_MRR_ERROR = 19U,
LPDDR4_INTR_PHY_MASTER_ERROR = 20U,
LPDDR4_INTR_WRLVL_REQ = 21U,
LPDDR4_INTR_RDLVL_REQ = 22U,
LPDDR4_INTR_RDLVL_GATE_REQ = 23U,
LPDDR4_INTR_CA_TRAINING_REQ = 24U,
LPDDR4_INTR_LEVELING_DONE = 25U,
LPDDR4_INTR_PHY_ERROR = 26U,
LPDDR4_INTR_MR_READ_DONE = 27U,
LPDDR4_INTR_TEMP_CHANGE = 28U,
LPDDR4_INTR_TEMP_ALERT = 29U,
LPDDR4_INTR_SW_DQS_COMPLETE = 30U,
LPDDR4_INTR_DQS_OSC_BV_UPDATED = 31U,
LPDDR4_INTR_DQS_OSC_OVERFLOW = 32U,
LPDDR4_INTR_DQS_OSC_VAR_OUT = 33U,
LPDDR4_INTR_MR_WRITE_DONE = 34U,
LPDDR4_INTR_INHIBIT_DRAM_DONE = 35U,
LPDDR4_INTR_DFI_INIT_STATE = 36U,
LPDDR4_INTR_DLL_RESYNC_DONE = 37U,
LPDDR4_INTR_TDFI_TO = 38U,
LPDDR4_INTR_DFS_DONE = 39U,
LPDDR4_INTR_DFS_STATUS = 40U,
LPDDR4_INTR_REFRESH_STATUS = 41U,
LPDDR4_INTR_ZQ_STATUS = 42U,
LPDDR4_INTR_SW_REQ_MODE = 43U,
LPDDR4_INTR_LOR_BITS = 44U
} lpddr4_intr_ctlinterrupt;
typedef enum {
LPDDR4_INTR_PHY_INDEP_INIT_DONE_BIT = 0U,
LPDDR4_INTR_PHY_INDEP_CONTROL_ERROR_BIT = 1U,
LPDDR4_INTR_PHY_INDEP_CA_PARITY_ERR_BIT = 2U,
LPDDR4_INTR_PHY_INDEP_RDLVL_ERROR_BIT = 3U,
LPDDR4_INTR_PHY_INDEP_RDLVL_G_ERROR_BIT = 4U,
LPDDR4_INTR_PHY_INDEP_WRLVL_ERROR_BIT = 5U,
LPDDR4_INTR_PHY_INDEP_CALVL_ERROR_BIT = 6U,
LPDDR4_INTR_PHY_INDEP_WDQLVL_ERROR_BIT = 7U,
LPDDR4_INTR_PHY_INDEP_UPDATE_ERROR_BIT = 8U,
LPDDR4_INTR_PHY_INDEP_RDLVL_REQ_BIT = 9U,
LPDDR4_INTR_PHY_INDEP_RDLVL_GATE_REQ_BIT = 10U,
LPDDR4_INTR_PHY_INDEP_WRLVL_REQ_BIT = 11U,
LPDDR4_INTR_PHY_INDEP_CALVL_REQ_BIT = 12U,
LPDDR4_INTR_PHY_INDEP_WDQLVL_REQ_BIT = 13U,
LPDDR4_INTR_PHY_INDEP_LVL_DONE_BIT = 14U,
LPDDR4_INTR_PHY_INDEP_BIST_DONE_BIT = 15U,
LPDDR4_INTR_PHY_INDEP_TDFI_INIT_TIME_OUT_BIT = 16U,
LPDDR4_INTR_PHY_INDEP_DLL_LOCK_STATE_CHANGE_BIT = 17U
} lpddr4_intr_phyindepinterrupt;
#endif /* LPDDR4_32BIT_IF_H */

View File

@ -0,0 +1,14 @@
/* SPDX-License-Identifier: BSD-3-Clause */
/*
* Cadence DDR Driver
*
* Copyright (C) 2012-2021 Cadence Design Systems, Inc.
* Copyright (C) 2018-2021 Texas Instruments Incorporated - https://www.ti.com/
*/
#ifndef LPDDR4_32BIT_OBJ_IF_H
#define LPDDR4_32BIT_OBJ_IF_H
#include "lpddr4_32bit_if.h"
#endif /* LPDDR4_32BIT_OBJ_IF_H */

View File

@ -0,0 +1,15 @@
/* SPDX-License-Identifier: BSD-3-Clause */
/*
* Cadence DDR Driver
*
* Copyright (C) 2012-2021 Cadence Design Systems, Inc.
* Copyright (C) 2018-2021 Texas Instruments Incorporated - https://www.ti.com/
*/
#ifndef LPDDR4_32BIT_STRUCTS_IF_H
#define LPDDR4_32BIT_STRUCTS_IF_H
#include <linux/types.h>
#include "lpddr4_32bit_if.h"
#endif /* LPDDR4_32BIT_STRUCTS_IF_H */

View File

@ -1,10 +1,9 @@
/* SPDX-License-Identifier: BSD-3-Clause */
/**********************************************************************
* Copyright (C) 2012-2019 Cadence Design Systems, Inc.
/*
* Cadence DDR Driver
*
* THIS FILE IS AUTOMATICALLY GENERATED, DO NOT EDIT
*
**********************************************************************
* Copyright (C) 2012-2021 Cadence Design Systems, Inc.
* Copyright (C) 2018-2021 Texas Instruments Incorporated - https://www.ti.com/
*/
#ifndef REG_LPDDR4_ADDRESS_SLICE_0_MACROS_H_

View File

@ -1,10 +1,9 @@
/* SPDX-License-Identifier: BSD-3-Clause */
/**********************************************************************
* Copyright (C) 2012-2019 Cadence Design Systems, Inc.
/*
* Cadence DDR Driver
*
* THIS FILE IS AUTOMATICALLY GENERATED, DO NOT EDIT
*
**********************************************************************
* Copyright (C) 2012-2021 Cadence Design Systems, Inc.
* Copyright (C) 2018-2021 Texas Instruments Incorporated - https://www.ti.com/
*/
#ifndef REG_LPDDR4_CTL_REGS_H_

View File

@ -0,0 +1,23 @@
/* SPDX-License-Identifier: BSD-3-Clause */
/*
* Cadence DDR Driver
*
* Copyright (C) 2012-2021 Cadence Design Systems, Inc.
* Copyright (C) 2018-2021 Texas Instruments Incorporated - https://www.ti.com/
*/
#ifndef LPDDR4_RW_MASKS_H_
#define LPDDR4_RW_MASKS_H_
#include <stdint.h>
extern u32 g_lpddr4_ddr_controller_rw_mask[459];
extern u32 g_lpddr4_pi_rw_mask[300];
extern u32 g_lpddr4_data_slice_0_rw_mask[140];
extern u32 g_lpddr4_data_slice_1_rw_mask[140];
extern u32 g_lpddr4_data_slice_2_rw_mask[140];
extern u32 g_lpddr4_data_slice_3_rw_mask[140];
extern u32 g_lpddr4_address_slice_0_rw_mask[52];
extern u32 g_lpddr4_phy_core_rw_mask[143];
#endif /* LPDDR4_RW_MASKS_H_ */

View File

@ -1,10 +1,9 @@
/* SPDX-License-Identifier: BSD-3-Clause */
/**********************************************************************
* Copyright (C) 2012-2019 Cadence Design Systems, Inc.
/*
* Cadence DDR Driver
*
* THIS FILE IS AUTOMATICALLY GENERATED, DO NOT EDIT
*
**********************************************************************
* Copyright (C) 2012-2021 Cadence Design Systems, Inc.
* Copyright (C) 2018-2021 Texas Instruments Incorporated - https://www.ti.com/
*/
#ifndef REG_LPDDR4_DATA_SLICE_0_MACROS_H_

View File

@ -1,10 +1,9 @@
/* SPDX-License-Identifier: BSD-3-Clause */
/**********************************************************************
* Copyright (C) 2012-2019 Cadence Design Systems, Inc.
/*
* Cadence DDR Driver
*
* THIS FILE IS AUTOMATICALLY GENERATED, DO NOT EDIT
*
**********************************************************************
* Copyright (C) 2012-2021 Cadence Design Systems, Inc.
* Copyright (C) 2018-2021 Texas Instruments Incorporated - https://www.ti.com/
*/
#ifndef REG_LPDDR4_DATA_SLICE_1_MACROS_H_

View File

@ -1,10 +1,9 @@
/* SPDX-License-Identifier: BSD-3-Clause */
/**********************************************************************
* Copyright (C) 2012-2019 Cadence Design Systems, Inc.
/*
* Cadence DDR Driver
*
* THIS FILE IS AUTOMATICALLY GENERATED, DO NOT EDIT
*
**********************************************************************
* Copyright (C) 2012-2021 Cadence Design Systems, Inc.
* Copyright (C) 2018-2021 Texas Instruments Incorporated - https://www.ti.com/
*/
#ifndef REG_LPDDR4_DATA_SLICE_2_MACROS_H_

View File

@ -1,10 +1,9 @@
/* SPDX-License-Identifier: BSD-3-Clause */
/**********************************************************************
* Copyright (C) 2012-2019 Cadence Design Systems, Inc.
/*
* Cadence DDR Driver
*
* THIS FILE IS AUTOMATICALLY GENERATED, DO NOT EDIT
*
**********************************************************************
* Copyright (C) 2012-2021 Cadence Design Systems, Inc.
* Copyright (C) 2018-2021 Texas Instruments Incorporated - https://www.ti.com/
*/
#ifndef REG_LPDDR4_DATA_SLICE_3_MACROS_H_

View File

@ -1,10 +1,9 @@
/* SPDX-License-Identifier: BSD-3-Clause */
/**********************************************************************
* Copyright (C) 2012-2019 Cadence Design Systems, Inc.
/*
* Cadence DDR Driver
*
* THIS FILE IS AUTOMATICALLY GENERATED, DO NOT EDIT
*
**********************************************************************
* Copyright (C) 2012-2021 Cadence Design Systems, Inc.
* Copyright (C) 2018-2021 Texas Instruments Incorporated - https://www.ti.com/
*/
#ifndef REG_LPDDR4_DDR_CONTROLLER_MACROS_H_

View File

@ -1,10 +1,9 @@
/* SPDX-License-Identifier: BSD-3-Clause */
/**********************************************************************
* Copyright (C) 2012-2019 Cadence Design Systems, Inc.
/*
* Cadence DDR Driver
*
* THIS FILE IS AUTOMATICALLY GENERATED, DO NOT EDIT
*
**********************************************************************
* Copyright (C) 2012-2021 Cadence Design Systems, Inc.
* Copyright (C) 2018-2021 Texas Instruments Incorporated - https://www.ti.com/
*/
#ifndef REG_LPDDR4_PHY_CORE_MACROS_H_

View File

@ -1,10 +1,9 @@
/* SPDX-License-Identifier: BSD-3-Clause */
/**********************************************************************
* Copyright (C) 2012-2019 Cadence Design Systems, Inc.
/*
* Cadence DDR Driver
*
* THIS FILE IS AUTOMATICALLY GENERATED, DO NOT EDIT
*
**********************************************************************
* Copyright (C) 2012-2021 Cadence Design Systems, Inc.
* Copyright (C) 2018-2021 Texas Instruments Incorporated - https://www.ti.com/
*/
#ifndef REG_LPDDR4_PI_MACROS_H_

View File

@ -1,8 +1,13 @@
# SPDX-License-Identifier: GPL-2.0+
#
# Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com/
# Copyright (C) 2019-2021 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
obj-$(CONFIG_K3_DDRSS) += k3-ddrss.o
obj-$(CONFIG_K3_DDRSS) += lpddr4_obj_if.o
obj-$(CONFIG_K3_DDRSS) += lpddr4.o
ccflags-$(CONFIG_K3_DDRSS) += -Idrivers/ram/k3-ddrss/
obj-$(CONFIG_K3_J721E_DDRSS) += lpddr4_32bit.o
obj-$(CONFIG_K3_J721E_DDRSS) += lpddr4_32bit_ctl_regs_rw_masks.o
ccflags-$(CONFIG_K3_J721E_DDRSS) += -Idrivers/ram/k3-ddrss/32bit/

View File

@ -1,119 +1,102 @@
/* SPDX-License-Identifier: BSD-3-Clause */
/******************************************************************************
/*
* Cadence DDR Driver
*
* 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)
*****************************************************************************
* Copyright (C) 2012-2021 Cadence Design Systems, Inc.
* Copyright (C) 2018-2021 Texas Instruments Incorporated - https://www.ti.com/
*/
#ifndef CPS_DRV_H_
#define CPS_DRV_H_
#include <stddef.h>
#include <inttypes.h>
#ifdef DEMO_TB
#include <cdn_demo.h>
#else
#include <asm/io.h>
#endif
/**
* \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)))
#define CPS_REG_READ(reg) (cps_regread((volatile u32 *)(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)))
#define CPS_REG_WRITE(reg, value) (cps_regwrite((volatile u32 *)(reg), (u32)(value)))
/**
* \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)))
#define CPS_FLD_READ(fld, reg_value) (cps_fldread((u32)(CPS_FLD_MASK(fld)), \
(u32)(CPS_FLD_SHIFT(fld)), \
(u32)(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)))
#define CPS_FLD_WRITE(fld, reg_value, value) (cps_fldwrite((u32)(CPS_FLD_MASK(fld)), \
(u32)(CPS_FLD_SHIFT(fld)), \
(u32)(reg_value), (u32)(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)))
#define CPS_FLD_SET(fld, reg_value) (cps_fldset((u32)(CPS_FLD_WIDTH(fld)), \
(u32)(CPS_FLD_MASK(fld)), \
(u32)(CPS_FLD_WOCLR(fld)), \
(u32)(reg_value)))
static inline uint32_t cps_fldread(uint32_t mask, uint32_t shift, uint32_t reg_value)
#ifdef CLR_USED
#define CPS_FLD_CLEAR(reg, fld, reg_value) (cps_fldclear((u32)(CPS_FLD_WIDTH(fld)), \
(u32)(CPS_FLD_MASK(fld)), \
(u32)(CPS_FLD_WOSET(fld)), \
(u32)(CPS_FLD_WOCLR(fld)), \
(u32)(reg_value)))
#endif
static inline u32 cps_regread(volatile u32 *reg);
static inline u32 cps_regread(volatile u32 *reg)
{
uint32_t result = (reg_value & mask) >> shift;
return (result);
return readl(reg);
}
/**
* \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)
static inline void cps_regwrite(volatile u32 *reg, u32 value);
static inline void cps_regwrite(volatile u32 *reg, u32 value)
{
uint32_t new_value = (value << shift) & mask;
writel(value, reg);
}
static inline u32 cps_fldread(u32 mask, u32 shift, u32 reg_value);
static inline u32 cps_fldread(u32 mask, u32 shift, u32 reg_value)
{
u32 result = (reg_value & mask) >> shift;
return result;
}
static inline u32 cps_fldwrite(u32 mask, u32 shift, u32 reg_value, u32 value);
static inline u32 cps_fldwrite(u32 mask, u32 shift, u32 reg_value, u32 value)
{
u32 new_value = (value << shift) & mask;
new_value = (reg_value & ~mask) | new_value;
return (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)
static inline u32 cps_fldset(u32 width, u32 mask, u32 is_woclr, u32 reg_value);
static inline u32 cps_fldset(u32 width, u32 mask, u32 is_woclr, u32 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;
}
u32 new_value = reg_value;
return (new_value);
if ((width == 1U) && (is_woclr == 0U))
new_value |= mask;
return new_value;
}
#ifdef CLR_USED
static inline u32 cps_fldclear(u32 width, u32 mask, u32 is_woset, u32 is_woclr, u32 reg_value);
static inline u32 cps_fldclear(u32 width, u32 mask, u32 is_woset, u32 is_woclr, u32 reg_value)
{
u32 new_value = reg_value;
if ((width == 1U) && (is_woset == 0U))
new_value = (new_value & ~mask) | ((is_woclr != 0U) ? mask : 0U);
return new_value;
}
#endif /* CLR_USED */
#endif /* CPS_DRV_H_ */

View File

@ -1,20 +1,20 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Texas Instruments' J721E DDRSS driver
* Texas Instruments' K3 DDRSS driver
*
* Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com/
* Copyright (C) 2020-2021 Texas Instruments Incorporated - http://www.ti.com/
*/
#include <common.h>
#include <clk.h>
#include <dm.h>
#include <dm/device_compat.h>
#include <ram.h>
#include <hang.h>
#include <log.h>
#include <ram.h>
#include <asm/io.h>
#include <power-domain.h>
#include <wait_bit.h>
#include <dm/device_compat.h>
#include "lpddr4_obj_if.h"
#include "lpddr4_if.h"
@ -26,7 +26,7 @@
#define CTRLMMR_DDR4_FSP_CLKCHNG_REQ_OFFS 0x80
#define CTRLMMR_DDR4_FSP_CLKCHNG_ACK_OFFS 0xc0
struct j721e_ddrss_desc {
struct k3_ddrss_desc {
struct udevice *dev;
void __iomem *ddrss_ss_cfg;
void __iomem *ddrss_ctrl_mmr;
@ -39,11 +39,20 @@ struct j721e_ddrss_desc {
u32 ddr_fhs_cnt;
};
static LPDDR4_OBJ *driverdt;
static lpddr4_obj *driverdt;
static lpddr4_config config;
static lpddr4_privatedata pd;
static struct j721e_ddrss_desc *ddrss;
static struct k3_ddrss_desc *ddrss;
struct reginitdata {
u32 ctl_regs[LPDDR4_INTR_CTL_REG_COUNT];
u16 ctl_regs_offs[LPDDR4_INTR_CTL_REG_COUNT];
u32 pi_regs[LPDDR4_INTR_PHY_INDEP_REG_COUNT];
u16 pi_regs_offs[LPDDR4_INTR_PHY_INDEP_REG_COUNT];
u32 phy_regs[LPDDR4_INTR_PHY_REG_COUNT];
u16 phy_regs_offs[LPDDR4_INTR_PHY_REG_COUNT];
};
#define TH_MACRO_EXP(fld, str) (fld##str)
@ -56,22 +65,42 @@ static struct j721e_ddrss_desc *ddrss;
#define str(s) #s
#define xstr(s) str(s)
#define CTL_SHIFT 11
#define PHY_SHIFT 11
#define PI_SHIFT 10
#define CTL_SHIFT 11
#define PHY_SHIFT 11
#define PI_SHIFT 10
#define DENALI_CTL_0_DRAM_CLASS_DDR4 0xA
#define DENALI_CTL_0_DRAM_CLASS_LPDDR4 0xB
#define TH_OFFSET_FROM_REG(REG, SHIFT, offset) do {\
char *i, *pstr= xstr(REG); offset = 0;\
char *i, *pstr = xstr(REG); offset = 0;\
for (i = &pstr[SHIFT]; *i != '\0'; ++i) {\
offset = offset * 10 + (*i - '0'); }\
offset = offset * 10 + (*i - '0'); } \
} while (0)
static void j721e_lpddr4_ack_freq_upd_req(void)
static u32 k3_lpddr4_read_ddr_type(void)
{
u32 status = 0U;
u32 offset = 0U;
u32 regval = 0U;
u32 dram_class = 0U;
TH_OFFSET_FROM_REG(LPDDR4__DRAM_CLASS__REG, CTL_SHIFT, offset);
status = driverdt->readreg(&pd, LPDDR4_CTL_REGS, offset, &regval);
if (status > 0U) {
printf("%s: Failed to read DRAM_CLASS\n", __func__);
hang();
}
dram_class = ((regval & TH_FLD_MASK(LPDDR4__DRAM_CLASS__FLD)) >>
TH_FLD_SHIFT(LPDDR4__DRAM_CLASS__FLD));
return dram_class;
}
static void k3_lpddr4_freq_update(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,
@ -83,7 +112,7 @@ static void j721e_lpddr4_ack_freq_upd_req(void)
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",
debug("%s: received freq change req: req type = %d, req no. = %d\n",
__func__, req_type, counter);
if (req_type == 1)
@ -110,15 +139,62 @@ static void j721e_lpddr4_ack_freq_upd_req(void)
}
}
static void j721e_lpddr4_info_handler(const lpddr4_privatedata * pd,
lpddr4_infotype infotype)
static void k3_lpddr4_ack_freq_upd_req(void)
{
if (infotype == LPDDR4_DRV_SOC_PLL_UPDATE) {
j721e_lpddr4_ack_freq_upd_req();
u32 dram_class;
debug("--->>> LPDDR4 Initialization is in progress ... <<<---\n");
dram_class = k3_lpddr4_read_ddr_type();
switch (dram_class) {
case DENALI_CTL_0_DRAM_CLASS_DDR4:
break;
case DENALI_CTL_0_DRAM_CLASS_LPDDR4:
k3_lpddr4_freq_update();
break;
default:
printf("Unrecognized dram_class cannot update frequency!\n");
}
}
static int j721e_ddrss_power_on(struct j721e_ddrss_desc *ddrss)
static int k3_ddrss_init_freq(struct k3_ddrss_desc *ddrss)
{
u32 dram_class;
int ret;
dram_class = k3_lpddr4_read_ddr_type();
switch (dram_class) {
case DENALI_CTL_0_DRAM_CLASS_DDR4:
/* Set to ddr_freq1 from DT for DDR4 */
ret = clk_set_rate(&ddrss->ddr_clk, ddrss->ddr_freq1);
break;
case DENALI_CTL_0_DRAM_CLASS_LPDDR4:
/* Set to bypass frequency for LPDDR4*/
ret = clk_set_rate(&ddrss->ddr_clk, clk_get_rate(&ddrss->osc_clk));
break;
default:
ret = -EINVAL;
printf("Unrecognized dram_class cannot init frequency!\n");
}
if (ret < 0)
dev_err(ddrss->dev, "ddr clk init failed: %d\n", ret);
else
ret = 0;
return ret;
}
static void k3_lpddr4_info_handler(const lpddr4_privatedata *pd,
lpddr4_infotype infotype)
{
if (infotype == LPDDR4_DRV_SOC_PLL_UPDATE)
k3_lpddr4_ack_freq_upd_req();
}
static int k3_ddrss_power_on(struct k3_ddrss_desc *ddrss)
{
int ret;
@ -139,9 +215,9 @@ static int j721e_ddrss_power_on(struct j721e_ddrss_desc *ddrss)
return 0;
}
static int j721e_ddrss_ofdata_to_priv(struct udevice *dev)
static int k3_ddrss_ofdata_to_priv(struct udevice *dev)
{
struct j721e_ddrss_desc *ddrss = dev_get_priv(dev);
struct k3_ddrss_desc *ddrss = dev_get_priv(dev);
phys_addr_t reg;
int ret;
@ -193,42 +269,37 @@ static int j721e_ddrss_ofdata_to_priv(struct udevice *dev)
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)
void k3_lpddr4_probe(void)
{
uint32_t status = 0U;
uint16_t configsize = 0U;
u32 status = 0U;
u16 configsize = 0U;
status = driverdt->probe(&config, &configsize);
if ((status != 0) || (configsize != sizeof(lpddr4_privatedata))
|| (configsize > SRAM_MAX)) {
printf("LPDDR4_Probe: FAIL\n");
printf("%s: FAIL\n", __func__);
hang();
} else {
debug("LPDDR4_Probe: PASS\n");
debug("%s: PASS\n", __func__);
}
}
void j721e_lpddr4_init(void)
void k3_lpddr4_init(void)
{
uint32_t status = 0U;
u32 status = 0U;
if ((sizeof(pd) != sizeof(lpddr4_privatedata))
|| (sizeof(pd) > SRAM_MAX)) {
printf("LPDDR4_Init: FAIL\n");
printf("%s: FAIL\n", __func__);
hang();
}
config.ctlbase = (struct lpddr4_ctlregs_s *)ddrss->ddrss_ss_cfg;
config.infohandler = (lpddr4_infocallback) j721e_lpddr4_info_handler;
config.infohandler = (lpddr4_infocallback) k3_lpddr4_info_handler;
status = driverdt->init(&pd, &config);
@ -236,140 +307,148 @@ void j721e_lpddr4_init(void)
(pd.ctlbase != (struct lpddr4_ctlregs_s *)config.ctlbase) ||
(pd.ctlinterrupthandler != config.ctlinterrupthandler) ||
(pd.phyindepinterrupthandler != config.phyindepinterrupthandler)) {
printf("LPDDR4_Init: FAIL\n");
printf("%s: FAIL\n", __func__);
hang();
} else {
debug("LPDDR4_Init: PASS\n");
debug("%s: PASS\n", __func__);
}
}
void populate_data_array_from_dt(lpddr4_reginitdata * reginit_data)
void populate_data_array_from_dt(struct reginitdata *reginit_data)
{
int ret, i;
ret = dev_read_u32_array(ddrss->dev, "ti,ctl-data",
(u32 *) reginit_data->denalictlreg,
LPDDR4_CTL_REG_COUNT);
(u32 *)reginit_data->ctl_regs,
LPDDR4_INTR_CTL_REG_COUNT);
if (ret)
printf("Error reading ctrl data\n");
printf("Error reading ctrl data %d\n", ret);
for (i = 0; i < LPDDR4_CTL_REG_COUNT; i++)
reginit_data->updatectlreg[i] = true;
for (i = 0; i < LPDDR4_INTR_CTL_REG_COUNT; i++)
reginit_data->ctl_regs_offs[i] = i;
ret = dev_read_u32_array(ddrss->dev, "ti,pi-data",
(u32 *) reginit_data->denaliphyindepreg,
LPDDR4_PHY_INDEP_REG_COUNT);
(u32 *)reginit_data->pi_regs,
LPDDR4_INTR_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;
for (i = 0; i < LPDDR4_INTR_PHY_INDEP_REG_COUNT; i++)
reginit_data->pi_regs_offs[i] = i;
ret = dev_read_u32_array(ddrss->dev, "ti,phy-data",
(u32 *) reginit_data->denaliphyreg,
LPDDR4_PHY_REG_COUNT);
(u32 *)reginit_data->phy_regs,
LPDDR4_INTR_PHY_REG_COUNT);
if (ret)
printf("Error reading PHY data\n");
printf("Error reading PHY data %d\n", ret);
for (i = 0; i < LPDDR4_PHY_REG_COUNT; i++)
reginit_data->updatephyreg[i] = true;
for (i = 0; i < LPDDR4_INTR_PHY_REG_COUNT; i++)
reginit_data->phy_regs_offs[i] = i;
}
void j721e_lpddr4_hardware_reg_init(void)
void k3_lpddr4_hardware_reg_init(void)
{
uint32_t status = 0U;
lpddr4_reginitdata reginitdata;
u32 status = 0U;
struct reginitdata reginitdata;
populate_data_array_from_dt(&reginitdata);
status = driverdt->writectlconfig(&pd, &reginitdata);
if (!status) {
status = driverdt->writephyindepconfig(&pd, &reginitdata);
}
if (!status) {
status = driverdt->writephyconfig(&pd, &reginitdata);
}
status = driverdt->writectlconfig(&pd, reginitdata.ctl_regs,
reginitdata.ctl_regs_offs,
LPDDR4_INTR_CTL_REG_COUNT);
if (!status)
status = driverdt->writephyindepconfig(&pd, reginitdata.pi_regs,
reginitdata.pi_regs_offs,
LPDDR4_INTR_PHY_INDEP_REG_COUNT);
if (!status)
status = driverdt->writephyconfig(&pd, reginitdata.phy_regs,
reginitdata.phy_regs_offs,
LPDDR4_INTR_PHY_REG_COUNT);
if (status) {
printf(" ERROR: LPDDR4_HardwareRegInit failed!!\n");
printf("%s: FAIL\n", __func__);
hang();
}
return;
}
void j721e_lpddr4_start(void)
void k3_lpddr4_start(void)
{
uint32_t status = 0U;
uint32_t regval = 0U;
uint32_t offset = 0U;
u32 status = 0U;
u32 regval = 0U;
u32 offset = 0U;
TH_OFFSET_FROM_REG(LPDDR4__START__REG, CTL_SHIFT, offset);
status = driverdt->readreg(&pd, LPDDR4_CTL_REGS, offset, &regval);
if ((status > 0U) || ((regval & TH_FLD_MASK(LPDDR4__START__FLD)) != 0U)) {
printf("LPDDR4_StartTest: FAIL\n");
printf("%s: Pre start FAIL\n", __func__);
hang();
}
status = driverdt->start(&pd);
if (status > 0U) {
printf("LPDDR4_StartTest: FAIL\n");
printf("%s: FAIL\n", __func__);
hang();
}
status = driverdt->readreg(&pd, LPDDR4_CTL_REGS, offset, &regval);
if ((status > 0U) || ((regval & TH_FLD_MASK(LPDDR4__START__FLD)) != 1U)) {
printf("LPDDR4_Start: FAIL\n");
printf("%s: Post start FAIL\n", __func__);
hang();
} else {
debug("LPDDR4_Start: PASS\n");
debug("%s: Post start PASS\n", __func__);
}
}
static int j721e_ddrss_probe(struct udevice *dev)
static int k3_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);
ret = k3_ddrss_ofdata_to_priv(dev);
if (ret)
return ret;
ddrss->dev = dev;
ret = j721e_ddrss_power_on(ddrss);
ret = k3_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();
k3_lpddr4_probe();
k3_lpddr4_init();
k3_lpddr4_hardware_reg_init();
ret = k3_ddrss_init_freq(ddrss);
if (ret)
return ret;
k3_lpddr4_start();
return ret;
}
static int j721e_ddrss_get_info(struct udevice *dev, struct ram_info *info)
static int k3_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 struct ram_ops k3_ddrss_ops = {
.get_info = k3_ddrss_get_info,
};
static const struct udevice_id j721e_ddrss_ids[] = {
static const struct udevice_id k3_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 = sizeof(struct j721e_ddrss_desc),
U_BOOT_DRIVER(k3_ddrss) = {
.name = "k3_ddrss",
.id = UCLASS_RAM,
.of_match = k3_ddrss_ids,
.ops = &k3_ddrss_ops,
.probe = k3_ddrss_probe,
.priv_auto = sizeof(struct k3_ddrss_desc),
};

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,73 @@
/* SPDX-License-Identifier: BSD-3-Clause */
/*
* Cadence DDR Driver
*
* Copyright (C) 2012-2021 Cadence Design Systems, Inc.
* Copyright (C) 2018-2021 Texas Instruments Incorporated - https://www.ti.com/
*/
#ifndef LPDDR4_H
#define LPDDR4_H
#include "lpddr4_ctl_regs.h"
#include "lpddr4_sanity.h"
#ifdef CONFIG_K3_AM64_DDRSS
#include "lpddr4_16bit.h"
#include "lpddr4_16bit_sanity.h"
#else
#include "lpddr4_32bit.h"
#include "lpddr4_32bit_sanity.h"
#endif
#ifdef REG_WRITE_VERIF
#include "lpddr4_ctl_regs_rw_masks.h"
#endif
#ifdef __cplusplus
extern "C" {
#endif
#define PRODUCT_ID (0x1046U)
#define LPDDR4_BIT_MASK (0x1U)
#define BYTE_MASK (0xffU)
#define NIBBLE_MASK (0xfU)
#define WORD_SHIFT (32U)
#define WORD_MASK (0xffffffffU)
#define SLICE_WIDTH (0x100)
#define CTL_OFFSET 0
#define PI_OFFSET (((u32)1) << 11)
#define PHY_OFFSET (((u32)1) << 12)
#define CTL_INT_MASK_ALL ((u32)LPDDR4_LOR_BITS - WORD_SHIFT)
#define PLL_READY (0x3U)
#define IO_CALIB_DONE ((u32)0x1U << 23U)
#define IO_CALIB_FIELD ((u32)NIBBLE_MASK << 28U)
#define IO_CALIB_STATE ((u32)0xBU << 28U)
#define RX_CAL_DONE ((u32)LPDDR4_BIT_MASK << 4U)
#define CA_TRAIN_RL (((u32)LPDDR4_BIT_MASK << 5U) | ((u32)LPDDR4_BIT_MASK << 4U))
#define WR_LVL_STATE (((u32)NIBBLE_MASK) << 13U)
#define GATE_LVL_ERROR_FIELDS (((u32)LPDDR4_BIT_MASK << 7U) | ((u32)LPDDR4_BIT_MASK << 6U))
#define READ_LVL_ERROR_FIELDS ((((u32)NIBBLE_MASK) << 28U) | (((u32)BYTE_MASK) << 16U))
#define DQ_LVL_STATUS (((u32)LPDDR4_BIT_MASK << 26U) | (((u32)BYTE_MASK) << 18U))
#define CDN_TRUE 1U
#define CDN_FALSE 0U
void lpddr4_setsettings(lpddr4_ctlregs *ctlregbase, const bool errorfound);
volatile u32 *lpddr4_addoffset(volatile u32 *addr, u32 regoffset);
u32 lpddr4_pollctlirq(const lpddr4_privatedata *pd, lpddr4_intr_ctlinterrupt irqbit, u32 delay);
bool lpddr4_checklvlerrors(const lpddr4_privatedata *pd, lpddr4_debuginfo *debuginfo, bool errfound);
void lpddr4_seterrors(lpddr4_ctlregs *ctlregbase, lpddr4_debuginfo *debuginfo, u8 *errfoundptr);
u32 lpddr4_enablepiinitiator(const lpddr4_privatedata *pd);
void lpddr4_checkwrlvlerror(lpddr4_ctlregs *ctlregbase, lpddr4_debuginfo *debuginfo, bool *errfoundptr);
u32 lpddr4_checkmmrreaderror(const lpddr4_privatedata *pd, u64 *mmrvalue, u8 *mrrstatus);
u32 lpddr4_getdslicemask(u32 dslicenum, u32 arrayoffset);
#ifdef __cplusplus
}
#endif
#endif /* LPDDR4_H */

View File

@ -0,0 +1,302 @@
// SPDX-License-Identifier: BSD-3-Clause
/*
* Cadence DDR Driver
*
* Copyright (C) 2012-2021 Cadence Design Systems, Inc.
* Copyright (C) 2018-2021 Texas Instruments Incorporated - https://www.ti.com/
*/
#include <errno.h>
#include "cps_drv_lpddr4.h"
#include "lpddr4_ctl_regs.h"
#include "lpddr4_if.h"
#include "lpddr4.h"
#include "lpddr4_structs_if.h"
static void lpddr4_setrxoffseterror(lpddr4_ctlregs *ctlregbase, lpddr4_debuginfo *debuginfo, bool *errorfound);
u32 lpddr4_enablepiinitiator(const lpddr4_privatedata *pd)
{
u32 result = 0U;
u32 regval = 0U;
lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *)pd->ctlbase;
regval = CPS_FLD_SET(LPDDR4__PI_INIT_LVL_EN__FLD, CPS_REG_READ(&(ctlregbase->LPDDR4__PI_INIT_LVL_EN__REG)));
regval = CPS_FLD_SET(LPDDR4__PI_NORMAL_LVL_SEQ__FLD, regval);
CPS_REG_WRITE((&(ctlregbase->LPDDR4__PI_INIT_LVL_EN__REG)), regval);
return result;
}
u32 lpddr4_getctlinterruptmask(const lpddr4_privatedata *pd, u64 *mask)
{
u32 result = 0U;
u32 lowermask = 0U;
result = lpddr4_getctlinterruptmasksf(pd, mask);
if (result == (u32)0) {
lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *)pd->ctlbase;
lowermask = (u32)(CPS_FLD_READ(LPDDR4__INT_MASK_0__FLD, CPS_REG_READ(&(ctlregbase->LPDDR4__INT_MASK_0__REG))));
*mask = (u64)(CPS_FLD_READ(LPDDR4__INT_MASK_1__FLD, CPS_REG_READ(&(ctlregbase->LPDDR4__INT_MASK_1__REG))));
*mask = (u64)((*mask << WORD_SHIFT) | lowermask);
}
return result;
}
u32 lpddr4_setctlinterruptmask(const lpddr4_privatedata *pd, const u64 *mask)
{
u32 result;
u32 regval = 0;
const u64 ui64one = 1ULL;
const u32 ui32irqcount = (u32)LPDDR4_INTR_LOR_BITS + 1U;
result = lpddr4_setctlinterruptmasksf(pd, mask);
if ((result == (u32)0) && (ui32irqcount < 64U)) {
if (*mask >= (ui64one << ui32irqcount))
result = (u32)EINVAL;
}
if (result == (u32)0) {
lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *)pd->ctlbase;
regval = (u32)(*mask & WORD_MASK);
regval = CPS_FLD_WRITE(LPDDR4__INT_MASK_0__FLD, CPS_REG_READ(&(ctlregbase->LPDDR4__INT_MASK_0__REG)), regval);
CPS_REG_WRITE(&(ctlregbase->LPDDR4__INT_MASK_0__REG), regval);
regval = (u32)((*mask >> WORD_SHIFT) & WORD_MASK);
regval = CPS_FLD_WRITE(LPDDR4__INT_MASK_1__FLD, CPS_REG_READ(&(ctlregbase->LPDDR4__INT_MASK_1__REG)), regval);
CPS_REG_WRITE(&(ctlregbase->LPDDR4__INT_MASK_1__REG), regval);
}
return result;
}
u32 lpddr4_checkctlinterrupt(const lpddr4_privatedata *pd, lpddr4_intr_ctlinterrupt intr, bool *irqstatus)
{
u32 result;
u32 ctlirqstatus = 0;
u32 fieldshift = 0;
result = LPDDR4_INTR_CheckCtlIntSF(pd, intr, irqstatus);
if (result == (u32)0) {
lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *)pd->ctlbase;
if ((u32)intr >= (u32)WORD_SHIFT) {
ctlirqstatus = CPS_REG_READ(&(ctlregbase->LPDDR4__INT_STATUS_1__REG));
fieldshift = (u32)intr - ((u32)WORD_SHIFT);
} else {
ctlirqstatus = CPS_REG_READ(&(ctlregbase->LPDDR4__INT_STATUS_0__REG));
fieldshift = (u32)intr;
}
if (fieldshift < WORD_SHIFT) {
if (((ctlirqstatus >> fieldshift) & LPDDR4_BIT_MASK) > 0U)
*irqstatus = true;
else
*irqstatus = false;
}
}
return result;
}
u32 lpddr4_ackctlinterrupt(const lpddr4_privatedata *pd, lpddr4_intr_ctlinterrupt intr)
{
u32 result = 0;
u32 regval = 0;
u32 localinterrupt = (u32)intr;
result = LPDDR4_INTR_AckCtlIntSF(pd, intr);
if (result == (u32)0) {
lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *)pd->ctlbase;
if (localinterrupt > WORD_SHIFT) {
localinterrupt = (localinterrupt - (u32)WORD_SHIFT);
regval = ((u32)LPDDR4_BIT_MASK << localinterrupt);
CPS_REG_WRITE(&(ctlregbase->LPDDR4__INT_ACK_1__REG), regval);
} else {
regval = ((u32)LPDDR4_BIT_MASK << localinterrupt);
CPS_REG_WRITE(&(ctlregbase->LPDDR4__INT_ACK_0__REG), regval);
}
}
return result;
}
void lpddr4_checkwrlvlerror(lpddr4_ctlregs *ctlregbase, lpddr4_debuginfo *debuginfo, bool *errfoundptr)
{
u32 regval;
u32 errbitmask = 0U;
u32 snum;
volatile u32 *regaddress;
regaddress = (volatile u32 *)(&(ctlregbase->LPDDR4__PHY_WRLVL_ERROR_OBS_0__REG));
errbitmask = (LPDDR4_BIT_MASK << 1) | (LPDDR4_BIT_MASK);
for (snum = 0U; snum < DSLICE_NUM; snum++) {
regval = CPS_REG_READ(regaddress);
if ((regval & errbitmask) != 0U) {
debuginfo->wrlvlerror = CDN_TRUE;
*errfoundptr = true;
}
regaddress = lpddr4_addoffset(regaddress, (u32)SLICE_WIDTH);
}
}
static void lpddr4_setrxoffseterror(lpddr4_ctlregs *ctlregbase, lpddr4_debuginfo *debuginfo, bool *errorfound)
{
volatile u32 *regaddress;
u32 snum = 0U;
u32 errbitmask = 0U;
u32 regval = 0U;
if (*errorfound == (bool)false) {
regaddress = (volatile u32 *)(&(ctlregbase->LPDDR4__PHY_RX_CAL_LOCK_OBS_0__REG));
errbitmask = (RX_CAL_DONE) | (NIBBLE_MASK);
for (snum = (u32)0U; snum < DSLICE_NUM; snum++) {
regval = CPS_FLD_READ(LPDDR4__PHY_RX_CAL_LOCK_OBS_0__FLD, CPS_REG_READ(regaddress));
if ((regval & errbitmask) != RX_CAL_DONE) {
debuginfo->rxoffseterror = (u8)true;
*errorfound = true;
}
regaddress = lpddr4_addoffset(regaddress, (u32)SLICE_WIDTH);
}
}
}
u32 lpddr4_getdebuginitinfo(const lpddr4_privatedata *pd, lpddr4_debuginfo *debuginfo)
{
u32 result = 0U;
bool errorfound = false;
result = lpddr4_getdebuginitinfosf(pd, debuginfo);
if (result == (u32)0) {
lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *)pd->ctlbase;
lpddr4_seterrors(ctlregbase, debuginfo, (u8 *)&errorfound);
lpddr4_setsettings(ctlregbase, errorfound);
lpddr4_setrxoffseterror(ctlregbase, debuginfo, &errorfound);
errorfound = (bool)lpddr4_checklvlerrors(pd, debuginfo, errorfound);
}
if (errorfound == (bool)true)
result = (u32)EPROTO;
return result;
}
u32 lpddr4_geteccenable(const lpddr4_privatedata *pd, lpddr4_eccenable *eccparam)
{
u32 result = 0U;
u32 fldval = 0U;
result = lpddr4_geteccenablesf(pd, eccparam);
if (result == (u32)0) {
lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *)pd->ctlbase;
fldval = CPS_FLD_READ(LPDDR4__ECC_ENABLE__FLD, CPS_REG_READ(&(ctlregbase->LPDDR4__ECC_ENABLE__REG)));
switch (fldval) {
case 3:
*eccparam = LPDDR4_ECC_ERR_DETECT_CORRECT;
break;
case 2:
*eccparam = LPDDR4_ECC_ERR_DETECT;
break;
case 1:
*eccparam = LPDDR4_ECC_ENABLED;
break;
default:
*eccparam = LPDDR4_ECC_DISABLED;
break;
}
}
return result;
}
u32 lpddr4_seteccenable(const lpddr4_privatedata *pd, const lpddr4_eccenable *eccparam)
{
u32 result = 0U;
u32 regval = 0U;
result = lpddr4_seteccenablesf(pd, eccparam);
if (result == (u32)0) {
lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *)pd->ctlbase;
regval = CPS_FLD_WRITE(LPDDR4__ECC_ENABLE__FLD, CPS_REG_READ(&(ctlregbase->LPDDR4__ECC_ENABLE__REG)), *eccparam);
CPS_REG_WRITE(&(ctlregbase->LPDDR4__ECC_ENABLE__REG), regval);
}
return result;
}
u32 lpddr4_getreducmode(const lpddr4_privatedata *pd, lpddr4_reducmode *mode)
{
u32 result = 0U;
result = lpddr4_getreducmodesf(pd, mode);
if (result == (u32)0) {
lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *)pd->ctlbase;
if (CPS_FLD_READ(LPDDR4__REDUC__FLD, CPS_REG_READ(&(ctlregbase->LPDDR4__REDUC__REG))) == 0U)
*mode = LPDDR4_REDUC_ON;
else
*mode = LPDDR4_REDUC_OFF;
}
return result;
}
u32 lpddr4_setreducmode(const lpddr4_privatedata *pd, const lpddr4_reducmode *mode)
{
u32 result = 0U;
u32 regval = 0U;
result = lpddr4_setreducmodesf(pd, mode);
if (result == (u32)0) {
lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *)pd->ctlbase;
regval = (u32)CPS_FLD_WRITE(LPDDR4__REDUC__FLD, CPS_REG_READ(&(ctlregbase->LPDDR4__REDUC__REG)), *mode);
CPS_REG_WRITE(&(ctlregbase->LPDDR4__REDUC__REG), regval);
}
return result;
}
u32 lpddr4_checkmmrreaderror(const lpddr4_privatedata *pd, u64 *mmrvalue, u8 *mrrstatus)
{
u32 lowerdata;
lpddr4_ctlregs *ctlregbase = (lpddr4_ctlregs *)pd->ctlbase;
u32 result = (u32)0;
if (lpddr4_pollctlirq(pd, LPDDR4_INTR_MRR_ERROR, 100) == 0U) {
*mrrstatus = (u8)CPS_FLD_READ(LPDDR4__MRR_ERROR_STATUS__FLD, CPS_REG_READ(&(ctlregbase->LPDDR4__MRR_ERROR_STATUS__REG)));
*mmrvalue = (u64)0;
result = (u32)EIO;
} else {
*mrrstatus = (u8)0;
lowerdata = CPS_REG_READ(&(ctlregbase->LPDDR4__PERIPHERAL_MRR_DATA_0__REG));
*mmrvalue = CPS_REG_READ(&(ctlregbase->LPDDR4__PERIPHERAL_MRR_DATA_1__REG));
*mmrvalue = (u64)((*mmrvalue << WORD_SHIFT) | lowerdata);
result = lpddr4_ackctlinterrupt(pd, LPDDR4_INTR_MR_READ_DONE);
}
return result;
}
#ifdef REG_WRITE_VERIF
u32 lpddr4_getdslicemask(u32 dslicenum, u32 arrayoffset)
{
u32 rwmask = 0U;
switch (dslicenum) {
case 0:
if (arrayoffset < DSLICE0_REG_COUNT)
rwmask = g_lpddr4_data_slice_0_rw_mask[arrayoffset];
break;
case 1:
if (arrayoffset < DSLICE1_REG_COUNT)
rwmask = g_lpddr4_data_slice_1_rw_mask[arrayoffset];
break;
case 2:
if (arrayoffset < DSLICE2_REG_COUNT)
rwmask = g_lpddr4_data_slice_2_rw_mask[arrayoffset];
break;
default:
if (arrayoffset < DSLICE3_REG_COUNT)
rwmask = g_lpddr4_data_slice_3_rw_mask[arrayoffset];
break;
}
return rwmask;
}
#endif

View File

@ -0,0 +1,30 @@
/* SPDX-License-Identifier: BSD-3-Clause */
/*
* Cadence DDR Driver
*
* Copyright (C) 2012-2021 Cadence Design Systems, Inc.
* Copyright (C) 2018-2021 Texas Instruments Incorporated - https://www.ti.com/
*/
#ifndef LPDDR4_32BIT_H
#define LPDDR4_32BIT_H
#define DSLICE_NUM (4U)
#define ASLICE_NUM (1U)
#ifdef __cplusplus
extern "C" {
#endif
#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)
#ifdef __cplusplus
}
#endif
#endif /* LPDDR4_32BIT_H */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,223 @@
/* SPDX-License-Identifier: BSD-3-Clause */
/*
* Cadence DDR Driver
*
* Copyright (C) 2012-2021 Cadence Design Systems, Inc.
* Copyright (C) 2018-2021 Texas Instruments Incorporated - https://www.ti.com/
*/
#ifndef LPDDR4_32BIT_SANITY_H
#define LPDDR4_32BIT_SANITY_H
#include <errno.h>
#include <linux/types.h>
#include <lpddr4_if.h>
#ifdef __cplusplus
extern "C" {
#endif
static inline u32 lpddr4_intr_sanityfunction1(const lpddr4_privatedata *pd, const lpddr4_intr_ctlinterrupt intr, const bool *irqstatus);
static inline u32 lpddr4_intr_sanityfunction2(const lpddr4_privatedata *pd, const lpddr4_intr_ctlinterrupt intr);
static inline u32 lpddr4_intr_sanityfunction3(const lpddr4_privatedata *pd, const lpddr4_intr_phyindepinterrupt intr, const bool *irqstatus);
static inline u32 lpddr4_intr_sanityfunction4(const lpddr4_privatedata *pd, const lpddr4_intr_phyindepinterrupt intr);
#define LPDDR4_INTR_CheckCtlIntSF lpddr4_intr_sanityfunction1
#define LPDDR4_INTR_AckCtlIntSF lpddr4_intr_sanityfunction2
#define LPDDR4_INTR_CheckPhyIndepIntSF lpddr4_intr_sanityfunction3
#define LPDDR4_INTR_AckPhyIndepIntSF lpddr4_intr_sanityfunction4
static inline u32 lpddr4_intr_sanityfunction1(const lpddr4_privatedata *pd, const lpddr4_intr_ctlinterrupt intr, const bool *irqstatus)
{
u32 ret = 0;
if (pd == NULL) {
ret = EINVAL;
} else if (irqstatus == NULL) {
ret = EINVAL;
} else if (
(intr != LPDDR4_INTR_RESET_DONE) &&
(intr != LPDDR4_INTR_BUS_ACCESS_ERROR) &&
(intr != LPDDR4_INTR_MULTIPLE_BUS_ACCESS_ERROR) &&
(intr != LPDDR4_INTR_ECC_MULTIPLE_CORR_ERROR) &&
(intr != LPDDR4_INTR_ECC_MULTIPLE_UNCORR_ERROR) &&
(intr != LPDDR4_INTR_ECC_WRITEBACK_EXEC_ERROR) &&
(intr != LPDDR4_INTR_ECC_SCRUB_DONE) &&
(intr != LPDDR4_INTR_ECC_SCRUB_ERROR) &&
(intr != LPDDR4_INTR_PORT_COMMAND_ERROR) &&
(intr != LPDDR4_INTR_MC_INIT_DONE) &&
(intr != LPDDR4_INTR_LP_DONE) &&
(intr != LPDDR4_INTR_BIST_DONE) &&
(intr != LPDDR4_INTR_WRAP_ERROR) &&
(intr != LPDDR4_INTR_INVALID_BURST_ERROR) &&
(intr != LPDDR4_INTR_RDLVL_ERROR) &&
(intr != LPDDR4_INTR_RDLVL_GATE_ERROR) &&
(intr != LPDDR4_INTR_WRLVL_ERROR) &&
(intr != LPDDR4_INTR_CA_TRAINING_ERROR) &&
(intr != LPDDR4_INTR_DFI_UPDATE_ERROR) &&
(intr != LPDDR4_INTR_MRR_ERROR) &&
(intr != LPDDR4_INTR_PHY_MASTER_ERROR) &&
(intr != LPDDR4_INTR_WRLVL_REQ) &&
(intr != LPDDR4_INTR_RDLVL_REQ) &&
(intr != LPDDR4_INTR_RDLVL_GATE_REQ) &&
(intr != LPDDR4_INTR_CA_TRAINING_REQ) &&
(intr != LPDDR4_INTR_LEVELING_DONE) &&
(intr != LPDDR4_INTR_PHY_ERROR) &&
(intr != LPDDR4_INTR_MR_READ_DONE) &&
(intr != LPDDR4_INTR_TEMP_CHANGE) &&
(intr != LPDDR4_INTR_TEMP_ALERT) &&
(intr != LPDDR4_INTR_SW_DQS_COMPLETE) &&
(intr != LPDDR4_INTR_DQS_OSC_BV_UPDATED) &&
(intr != LPDDR4_INTR_DQS_OSC_OVERFLOW) &&
(intr != LPDDR4_INTR_DQS_OSC_VAR_OUT) &&
(intr != LPDDR4_INTR_MR_WRITE_DONE) &&
(intr != LPDDR4_INTR_INHIBIT_DRAM_DONE) &&
(intr != LPDDR4_INTR_DFI_INIT_STATE) &&
(intr != LPDDR4_INTR_DLL_RESYNC_DONE) &&
(intr != LPDDR4_INTR_TDFI_TO) &&
(intr != LPDDR4_INTR_DFS_DONE) &&
(intr != LPDDR4_INTR_DFS_STATUS) &&
(intr != LPDDR4_INTR_REFRESH_STATUS) &&
(intr != LPDDR4_INTR_ZQ_STATUS) &&
(intr != LPDDR4_INTR_SW_REQ_MODE) &&
(intr != LPDDR4_INTR_LOR_BITS)
) {
ret = EINVAL;
} else {
}
return ret;
}
static inline u32 lpddr4_intr_sanityfunction2(const lpddr4_privatedata *pd, const lpddr4_intr_ctlinterrupt intr)
{
u32 ret = 0;
if (pd == NULL) {
ret = EINVAL;
} else if (
(intr != LPDDR4_INTR_RESET_DONE) &&
(intr != LPDDR4_INTR_BUS_ACCESS_ERROR) &&
(intr != LPDDR4_INTR_MULTIPLE_BUS_ACCESS_ERROR) &&
(intr != LPDDR4_INTR_ECC_MULTIPLE_CORR_ERROR) &&
(intr != LPDDR4_INTR_ECC_MULTIPLE_UNCORR_ERROR) &&
(intr != LPDDR4_INTR_ECC_WRITEBACK_EXEC_ERROR) &&
(intr != LPDDR4_INTR_ECC_SCRUB_DONE) &&
(intr != LPDDR4_INTR_ECC_SCRUB_ERROR) &&
(intr != LPDDR4_INTR_PORT_COMMAND_ERROR) &&
(intr != LPDDR4_INTR_MC_INIT_DONE) &&
(intr != LPDDR4_INTR_LP_DONE) &&
(intr != LPDDR4_INTR_BIST_DONE) &&
(intr != LPDDR4_INTR_WRAP_ERROR) &&
(intr != LPDDR4_INTR_INVALID_BURST_ERROR) &&
(intr != LPDDR4_INTR_RDLVL_ERROR) &&
(intr != LPDDR4_INTR_RDLVL_GATE_ERROR) &&
(intr != LPDDR4_INTR_WRLVL_ERROR) &&
(intr != LPDDR4_INTR_CA_TRAINING_ERROR) &&
(intr != LPDDR4_INTR_DFI_UPDATE_ERROR) &&
(intr != LPDDR4_INTR_MRR_ERROR) &&
(intr != LPDDR4_INTR_PHY_MASTER_ERROR) &&
(intr != LPDDR4_INTR_WRLVL_REQ) &&
(intr != LPDDR4_INTR_RDLVL_REQ) &&
(intr != LPDDR4_INTR_RDLVL_GATE_REQ) &&
(intr != LPDDR4_INTR_CA_TRAINING_REQ) &&
(intr != LPDDR4_INTR_LEVELING_DONE) &&
(intr != LPDDR4_INTR_PHY_ERROR) &&
(intr != LPDDR4_INTR_MR_READ_DONE) &&
(intr != LPDDR4_INTR_TEMP_CHANGE) &&
(intr != LPDDR4_INTR_TEMP_ALERT) &&
(intr != LPDDR4_INTR_SW_DQS_COMPLETE) &&
(intr != LPDDR4_INTR_DQS_OSC_BV_UPDATED) &&
(intr != LPDDR4_INTR_DQS_OSC_OVERFLOW) &&
(intr != LPDDR4_INTR_DQS_OSC_VAR_OUT) &&
(intr != LPDDR4_INTR_MR_WRITE_DONE) &&
(intr != LPDDR4_INTR_INHIBIT_DRAM_DONE) &&
(intr != LPDDR4_INTR_DFI_INIT_STATE) &&
(intr != LPDDR4_INTR_DLL_RESYNC_DONE) &&
(intr != LPDDR4_INTR_TDFI_TO) &&
(intr != LPDDR4_INTR_DFS_DONE) &&
(intr != LPDDR4_INTR_DFS_STATUS) &&
(intr != LPDDR4_INTR_REFRESH_STATUS) &&
(intr != LPDDR4_INTR_ZQ_STATUS) &&
(intr != LPDDR4_INTR_SW_REQ_MODE) &&
(intr != LPDDR4_INTR_LOR_BITS)
) {
ret = EINVAL;
} else {
}
return ret;
}
static inline u32 lpddr4_intr_sanityfunction3(const lpddr4_privatedata *pd, const lpddr4_intr_phyindepinterrupt intr, const bool *irqstatus)
{
u32 ret = 0;
if (pd == NULL) {
ret = EINVAL;
} else if (irqstatus == NULL) {
ret = EINVAL;
} else if (
(intr != LPDDR4_INTR_PHY_INDEP_INIT_DONE_BIT) &&
(intr != LPDDR4_INTR_PHY_INDEP_CONTROL_ERROR_BIT) &&
(intr != LPDDR4_INTR_PHY_INDEP_CA_PARITY_ERR_BIT) &&
(intr != LPDDR4_INTR_PHY_INDEP_RDLVL_ERROR_BIT) &&
(intr != LPDDR4_INTR_PHY_INDEP_RDLVL_G_ERROR_BIT) &&
(intr != LPDDR4_INTR_PHY_INDEP_WRLVL_ERROR_BIT) &&
(intr != LPDDR4_INTR_PHY_INDEP_CALVL_ERROR_BIT) &&
(intr != LPDDR4_INTR_PHY_INDEP_WDQLVL_ERROR_BIT) &&
(intr != LPDDR4_INTR_PHY_INDEP_UPDATE_ERROR_BIT) &&
(intr != LPDDR4_INTR_PHY_INDEP_RDLVL_REQ_BIT) &&
(intr != LPDDR4_INTR_PHY_INDEP_RDLVL_GATE_REQ_BIT) &&
(intr != LPDDR4_INTR_PHY_INDEP_WRLVL_REQ_BIT) &&
(intr != LPDDR4_INTR_PHY_INDEP_CALVL_REQ_BIT) &&
(intr != LPDDR4_INTR_PHY_INDEP_WDQLVL_REQ_BIT) &&
(intr != LPDDR4_INTR_PHY_INDEP_LVL_DONE_BIT) &&
(intr != LPDDR4_INTR_PHY_INDEP_BIST_DONE_BIT) &&
(intr != LPDDR4_INTR_PHY_INDEP_TDFI_INIT_TIME_OUT_BIT) &&
(intr != LPDDR4_INTR_PHY_INDEP_DLL_LOCK_STATE_CHANGE_BIT)
) {
ret = EINVAL;
} else {
}
return ret;
}
static inline u32 lpddr4_intr_sanityfunction4(const lpddr4_privatedata *pd, const lpddr4_intr_phyindepinterrupt intr)
{
u32 ret = 0;
if (pd == NULL) {
ret = EINVAL;
} else if (
(intr != LPDDR4_INTR_PHY_INDEP_INIT_DONE_BIT) &&
(intr != LPDDR4_INTR_PHY_INDEP_CONTROL_ERROR_BIT) &&
(intr != LPDDR4_INTR_PHY_INDEP_CA_PARITY_ERR_BIT) &&
(intr != LPDDR4_INTR_PHY_INDEP_RDLVL_ERROR_BIT) &&
(intr != LPDDR4_INTR_PHY_INDEP_RDLVL_G_ERROR_BIT) &&
(intr != LPDDR4_INTR_PHY_INDEP_WRLVL_ERROR_BIT) &&
(intr != LPDDR4_INTR_PHY_INDEP_CALVL_ERROR_BIT) &&
(intr != LPDDR4_INTR_PHY_INDEP_WDQLVL_ERROR_BIT) &&
(intr != LPDDR4_INTR_PHY_INDEP_UPDATE_ERROR_BIT) &&
(intr != LPDDR4_INTR_PHY_INDEP_RDLVL_REQ_BIT) &&
(intr != LPDDR4_INTR_PHY_INDEP_RDLVL_GATE_REQ_BIT) &&
(intr != LPDDR4_INTR_PHY_INDEP_WRLVL_REQ_BIT) &&
(intr != LPDDR4_INTR_PHY_INDEP_CALVL_REQ_BIT) &&
(intr != LPDDR4_INTR_PHY_INDEP_WDQLVL_REQ_BIT) &&
(intr != LPDDR4_INTR_PHY_INDEP_LVL_DONE_BIT) &&
(intr != LPDDR4_INTR_PHY_INDEP_BIST_DONE_BIT) &&
(intr != LPDDR4_INTR_PHY_INDEP_TDFI_INIT_TIME_OUT_BIT) &&
(intr != LPDDR4_INTR_PHY_INDEP_DLL_LOCK_STATE_CHANGE_BIT)
) {
ret = EINVAL;
} else {
}
return ret;
}
#ifdef __cplusplus
}
#endif
#endif /* LPDDR4_32BIT_SANITY_H */

View File

@ -1,578 +1,144 @@
/* 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.
**********************************************************************
/*
* Cadence DDR Driver
*
* Copyright (C) 2012-2021 Cadence Design Systems, Inc.
* Copyright (C) 2018-2021 Texas Instruments Incorporated - https://www.ti.com/
*/
#ifndef LPDDR4_IF_H
#define LPDDR4_IF_H
#include <linux/types.h>
#ifdef CONFIG_K3_AM64_DDRSS
#include <lpddr4_16bit_if.h>
#else
#include <lpddr4_32bit_if.h>
#endif
/** @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
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
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
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
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
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
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
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);
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);
typedef void (*lpddr4_ctlcallback)(const lpddr4_privatedata *pd, lpddr4_intr_ctlinterrupt ctlinterrupt, u8 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);
typedef void (*lpddr4_phyindepcallback)(const lpddr4_privatedata *pd, lpddr4_intr_phyindepinterrupt phyindepinterrupt, u8 chipselect);
/**
* @}
*/
u32 lpddr4_probe(const lpddr4_config *config, u16 *configsize);
/** @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.
* @{
*/
u32 lpddr4_init(lpddr4_privatedata *pd, const lpddr4_config *cfg);
/**********************************************************************
* API methods
**********************************************************************/
u32 lpddr4_start(const lpddr4_privatedata *pd);
/**
* 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);
u32 lpddr4_readreg(const lpddr4_privatedata *pd, lpddr4_regblock cpp, u32 regoffset, u32 *regvalue);
/**
* 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);
u32 lpddr4_writereg(const lpddr4_privatedata *pd, lpddr4_regblock cpp, u32 regoffset, u32 regvalue);
/**
* Start the driver.
* @param[in] pD Driver state info specific to this instance.
*/
uint32_t lpddr4_start(const lpddr4_privatedata* pd);
u32 lpddr4_getmmrregister(const lpddr4_privatedata *pd, u32 readmoderegval, u64 *mmrvalue, u8 *mmrstatus);
/**
* 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);
u32 lpddr4_setmmrregister(const lpddr4_privatedata *pd, u32 writemoderegval, u8 *mrwstatus);
/**
* 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);
u32 lpddr4_writectlconfig(const lpddr4_privatedata *pd, u32 regvalues[], u16 regnum[], u16 regcount);
/**
* 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);
u32 lpddr4_writephyconfig(const lpddr4_privatedata *pd, u32 regvalues[], u16 regnum[], u16 regcount);
/**
* 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);
u32 lpddr4_writephyindepconfig(const lpddr4_privatedata *pd, u32 regvalues[], u16 regnum[], u16 regcount);
/**
* 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);
u32 lpddr4_readctlconfig(const lpddr4_privatedata *pd, u32 regvalues[], u16 regnum[], u16 regcount);
/**
* 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);
u32 lpddr4_readphyconfig(const lpddr4_privatedata *pd, u32 regvalues[], u16 regnum[], u16 regcount);
/**
* 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);
u32 lpddr4_readphyindepconfig(const lpddr4_privatedata *pd, u32 regvalues[], u16 regnum[], u16 regcount);
/**
* 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);
u32 lpddr4_getctlinterruptmask(const lpddr4_privatedata *pd, u64 *mask);
/**
* 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);
u32 lpddr4_setctlinterruptmask(const lpddr4_privatedata *pd, const u64 *mask);
/**
* 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);
u32 lpddr4_checkctlinterrupt(const lpddr4_privatedata *pd, lpddr4_intr_ctlinterrupt intr, bool *irqstatus);
/**
* 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);
u32 lpddr4_ackctlinterrupt(const lpddr4_privatedata *pd, lpddr4_intr_ctlinterrupt intr);
/**
* 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);
u32 lpddr4_getphyindepinterruptmask(const lpddr4_privatedata *pd, u32 *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);
u32 lpddr4_setphyindepinterruptmask(const lpddr4_privatedata *pd, const u32 *mask);
/**
* 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);
u32 lpddr4_checkphyindepinterrupt(const lpddr4_privatedata *pd, lpddr4_intr_phyindepinterrupt intr, bool *irqstatus);
/**
* 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);
u32 lpddr4_ackphyindepinterrupt(const lpddr4_privatedata *pd, lpddr4_intr_phyindepinterrupt intr);
/**
* 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);
u32 lpddr4_getdebuginitinfo(const lpddr4_privatedata *pd, lpddr4_debuginfo *debuginfo);
/**
* 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);
u32 lpddr4_getlpiwakeuptime(const lpddr4_privatedata *pd, const lpddr4_lpiwakeupparam *lpiwakeupparam, const lpddr4_ctlfspnum *fspnum, u32 *cycles);
/**
* 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);
u32 lpddr4_setlpiwakeuptime(const lpddr4_privatedata *pd, const lpddr4_lpiwakeupparam *lpiwakeupparam, const lpddr4_ctlfspnum *fspnum, const u32 *cycles);
/**
* 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);
u32 lpddr4_geteccenable(const lpddr4_privatedata *pd, lpddr4_eccenable *eccparam);
/**
* 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);
u32 lpddr4_seteccenable(const lpddr4_privatedata *pd, const lpddr4_eccenable *eccparam);
/**
* 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);
u32 lpddr4_getreducmode(const lpddr4_privatedata *pd, lpddr4_reducmode *mode);
/**
* 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);
u32 lpddr4_setreducmode(const lpddr4_privatedata *pd, const lpddr4_reducmode *mode);
/**
* 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);
u32 lpddr4_getdbireadmode(const lpddr4_privatedata *pd, bool *on_off);
/**
* 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);
u32 lpddr4_getdbiwritemode(const lpddr4_privatedata *pd, bool *on_off);
/**
* 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);
u32 lpddr4_setdbimode(const lpddr4_privatedata *pd, const lpddr4_dbimode *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);
u32 lpddr4_getrefreshrate(const lpddr4_privatedata *pd, const lpddr4_ctlfspnum *fspnum, u32 *tref, u32 *tras_max);
/**
* 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);
u32 lpddr4_setrefreshrate(const lpddr4_privatedata *pd, const lpddr4_ctlfspnum *fspnum, const u32 *tref, const u32 *tras_max);
/**
* 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);
u32 lpddr4_refreshperchipselect(const lpddr4_privatedata *pd, const u32 trefinterval);
#endif /* LPDDR4_IF_H */

View File

@ -1,54 +1,50 @@
// 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.
**********************************************************************
/*
* Cadence DDR Driver
*
* Copyright (C) 2012-2021 Cadence Design Systems, Inc.
* Copyright (C) 2018-2021 Texas Instruments Incorporated - https://www.ti.com/
*/
#include "lpddr4_obj_if.h"
LPDDR4_OBJ *lpddr4_getinstance(void)
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,
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;

View File

@ -1,383 +1,86 @@
/* 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.
**********************************************************************
/*
* Cadence DDR Driver
*
* Copyright (C) 2012-2021 Cadence Design Systems, Inc.
* Copyright (C) 2018-2021 Texas Instruments Incorporated - https://www.ti.com/
*/
#ifndef LPDDR4_OBJ_IF_H
#define LPDDR4_OBJ_IF_H
#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.
* @{
*/
typedef struct lpddr4_obj_s {
u32 (*probe)(const lpddr4_config *config, u16 *configsize);
/**********************************************************************
* 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);
u32 (*init)(lpddr4_privatedata *pd, const lpddr4_config *cfg);
/**
* 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);
u32 (*start)(const lpddr4_privatedata *pd);
/**
* Start the driver.
* @param[in] pD Driver state info specific to this instance.
*/
uint32_t (*start)(const lpddr4_privatedata* pd);
u32 (*readreg)(const lpddr4_privatedata *pd, lpddr4_regblock cpp, u32 regoffset, u32 *regvalue);
/**
* 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);
u32 (*writereg)(const lpddr4_privatedata *pd, lpddr4_regblock cpp, u32 regoffset, u32 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);
u32 (*getmmrregister)(const lpddr4_privatedata *pd, u32 readmoderegval, u64 *mmrvalue, u8 *mmrstatus);
/**
* 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);
u32 (*setmmrregister)(const lpddr4_privatedata *pd, u32 writemoderegval, u8 *mrwstatus);
/**
* 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);
u32 (*writectlconfig)(const lpddr4_privatedata *pd, u32 regvalues[], u16 regnum[], u16 regcount);
/**
* 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);
u32 (*writephyconfig)(const lpddr4_privatedata *pd, u32 regvalues[], u16 regnum[], u16 regcount);
/**
* 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);
u32 (*writephyindepconfig)(const lpddr4_privatedata *pd, u32 regvalues[], u16 regnum[], u16 regcount);
/**
* 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);
u32 (*readctlconfig)(const lpddr4_privatedata *pd, u32 regvalues[], u16 regnum[], u16 regcount);
/**
* 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);
u32 (*readphyconfig)(const lpddr4_privatedata *pd, u32 regvalues[], u16 regnum[], u16 regcount);
/**
* 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);
u32 (*readphyindepconfig)(const lpddr4_privatedata *pd, u32 regvalues[], u16 regnum[], u16 regcount);
/**
* 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);
u32 (*getctlinterruptmask)(const lpddr4_privatedata *pd, u64 *mask);
/**
* 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);
u32 (*setctlinterruptmask)(const lpddr4_privatedata *pd, const u64 *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);
u32 (*checkctlinterrupt)(const lpddr4_privatedata *pd, lpddr4_intr_ctlinterrupt intr, bool *irqstatus);
/**
* 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);
u32 (*ackctlinterrupt)(const lpddr4_privatedata *pd, lpddr4_intr_ctlinterrupt intr);
/**
* 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);
u32 (*getphyindepinterruptmask)(const lpddr4_privatedata *pd, u32 *mask);
/**
* 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);
u32 (*setphyindepinterruptmask)(const lpddr4_privatedata *pd, const u32 *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);
u32 (*checkphyindepinterrupt)(const lpddr4_privatedata *pd, lpddr4_intr_phyindepinterrupt intr, bool *irqstatus);
/**
* 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);
u32 (*ackphyindepinterrupt)(const lpddr4_privatedata *pd, lpddr4_intr_phyindepinterrupt intr);
/**
* 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);
u32 (*getdebuginitinfo)(const lpddr4_privatedata *pd, lpddr4_debuginfo *debuginfo);
/**
* 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);
u32 (*getlpiwakeuptime)(const lpddr4_privatedata *pd, const lpddr4_lpiwakeupparam *lpiwakeupparam, const lpddr4_ctlfspnum *fspnum, u32 *cycles);
/**
* 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);
u32 (*setlpiwakeuptime)(const lpddr4_privatedata *pd, const lpddr4_lpiwakeupparam *lpiwakeupparam, const lpddr4_ctlfspnum *fspnum, const u32 *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);
u32 (*geteccenable)(const lpddr4_privatedata *pd, lpddr4_eccenable *eccparam);
/**
* 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);
u32 (*seteccenable)(const lpddr4_privatedata *pd, const 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);
u32 (*getreducmode)(const lpddr4_privatedata *pd, lpddr4_reducmode *mode);
/**
* 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);
u32 (*setreducmode)(const lpddr4_privatedata *pd, const 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);
u32 (*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 read value
* @return CDN_EOK on success.
* @return EINVAL if on_off is NULL
*/
uint32_t (*getdbireadmode)(const lpddr4_privatedata* pd, bool* on_off);
u32 (*getdbiwritemode)(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);
u32 (*setdbimode)(const lpddr4_privatedata *pd, const lpddr4_dbimode *mode);
/**
* 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);
u32 (*getrefreshrate)(const lpddr4_privatedata *pd, const lpddr4_ctlfspnum *fspnum, u32 *tref, u32 *tras_max);
/**
* 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);
u32 (*setrefreshrate)(const lpddr4_privatedata *pd, const lpddr4_ctlfspnum *fspnum, const u32 *tref, const u32 *tras_max);
/**
* 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);
u32 (*refreshperchipselect)(const lpddr4_privatedata *pd, const u32 trefinterval);
} lpddr4_obj;
/**
* 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);
extern lpddr4_obj *lpddr4_getinstance(void);
} 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 */
#endif /* lpddr4_obj_if_h */

File diff suppressed because it is too large Load Diff

View File

@ -1,121 +1,51 @@
/* 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.
**********************************************************************
/*
* Cadence DDR Driver
*
* Copyright (C) 2012-2021 Cadence Design Systems, Inc.
* Copyright (C) 2018-2021 Texas Instruments Incorporated - https://www.ti.com/
*/
#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 */
struct lpddr4_config_s {
struct lpddr4_ctlregs_s *ctlbase;
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 */
struct lpddr4_privatedata_s {
struct lpddr4_ctlregs_s *ctlbase;
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;
struct lpddr4_debuginfo_s {
u8 pllerror;
u8 iocaliberror;
u8 rxoffseterror;
u8 catraingerror;
u8 wrlvlerror;
u8 gatelvlerror;
u8 readlvlerror;
u8 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];
struct lpddr4_fspmoderegs_s {
u8 mr1data_fn[LPDDR4_INTR_MAX_CS];
u8 mr2data_fn[LPDDR4_INTR_MAX_CS];
u8 mr3data_fn[LPDDR4_INTR_MAX_CS];
u8 mr11data_fn[LPDDR4_INTR_MAX_CS];
u8 mr12data_fn[LPDDR4_INTR_MAX_CS];
u8 mr13data_fn[LPDDR4_INTR_MAX_CS];
u8 mr14data_fn[LPDDR4_INTR_MAX_CS];
u8 mr22data_fn[LPDDR4_INTR_MAX_CS];
};
#endif /* LPDDR4_STRUCTS_IF_H */