130c8a20dSKhristine Andreea Barbulescu /* 2*a60aeae7SKhristine Andreea Barbulescu * Copyright 2020-2026 NXP 330c8a20dSKhristine Andreea Barbulescu * 430c8a20dSKhristine Andreea Barbulescu * SPDX-License-Identifier: BSD-3-Clause 530c8a20dSKhristine Andreea Barbulescu */ 630c8a20dSKhristine Andreea Barbulescu 730c8a20dSKhristine Andreea Barbulescu #ifndef DDR_UTILS_H 830c8a20dSKhristine Andreea Barbulescu #define DDR_UTILS_H 930c8a20dSKhristine Andreea Barbulescu 1030c8a20dSKhristine Andreea Barbulescu #include <stdbool.h> 1130c8a20dSKhristine Andreea Barbulescu #include <stdlib.h> 1230c8a20dSKhristine Andreea Barbulescu 1330c8a20dSKhristine Andreea Barbulescu #include <lib/mmio.h> 1430c8a20dSKhristine Andreea Barbulescu 1530c8a20dSKhristine Andreea Barbulescu #include <platform_def.h> 1630c8a20dSKhristine Andreea Barbulescu 1730c8a20dSKhristine Andreea Barbulescu /* Possible errors */ 1830c8a20dSKhristine Andreea Barbulescu #define NO_ERR 0x00000000U 1930c8a20dSKhristine Andreea Barbulescu #define TIMEOUT_ERR 0x00000002U 2030c8a20dSKhristine Andreea Barbulescu #define TRAINING_FAILED 0x00000003U 2130c8a20dSKhristine Andreea Barbulescu #define BITFIELD_EXCEEDED 0x00000004U 2230c8a20dSKhristine Andreea Barbulescu #define DEASSERT_FAILED 0x00000005U 2330c8a20dSKhristine Andreea Barbulescu 24a4efd428SKhristine Andreea Barbulescu /* DDRC related */ 25a4efd428SKhristine Andreea Barbulescu #define DDRC_BASE 0x403C0000U 26a4efd428SKhristine Andreea Barbulescu #define OFFSET_DDRC_SWCTL 0x320U 27a4efd428SKhristine Andreea Barbulescu #define OFFSET_DDRC_DFIMISC 0x1B0U 28*a60aeae7SKhristine Andreea Barbulescu #define OFFSET_DDRC_DFISTAT 0x1BCU 29a4efd428SKhristine Andreea Barbulescu #define OFFSET_DDRC_PWRCTL 0x30U 30a4efd428SKhristine Andreea Barbulescu #define OFFSET_DDRC_SWSTAT 0x324U 31*a60aeae7SKhristine Andreea Barbulescu #define OFFSET_DDRC_STAT 0x04U 32a4efd428SKhristine Andreea Barbulescu #define OFFSET_DDRC_DFITMG0 0x190U 33a4efd428SKhristine Andreea Barbulescu #define OFFSET_DDRC_DBG1 0x304U 34a4efd428SKhristine Andreea Barbulescu 35*a60aeae7SKhristine Andreea Barbulescu #define OFFSET_DDRC_DRAMTMG2 0x108U 36*a60aeae7SKhristine Andreea Barbulescu #define OFFSET_DDRC_INIT6 0xE8U 37*a60aeae7SKhristine Andreea Barbulescu #define OFFSET_DDRC_INIT7 0xECU 38*a60aeae7SKhristine Andreea Barbulescu #define OFFSET_DDRC_RANKCTL 0xF4U 39*a60aeae7SKhristine Andreea Barbulescu #define OFFSET_DDRC_DFITMG1 0x194U 40*a60aeae7SKhristine Andreea Barbulescu 41a4efd428SKhristine Andreea Barbulescu /* DDRC masks and values */ 42a4efd428SKhristine Andreea Barbulescu #define MSTR_LPDDR4_VAL 0x20U 43a4efd428SKhristine Andreea Barbulescu #define SWSTAT_SW_DONE 1U 44a4efd428SKhristine Andreea Barbulescu #define SWSTAT_SW_NOT_DONE 0U 45a4efd428SKhristine Andreea Barbulescu #define SWCTL_SWDONE_DONE 0x1U 46a4efd428SKhristine Andreea Barbulescu #define SWCTL_SWDONE_ENABLE 0x0U 47a4efd428SKhristine Andreea Barbulescu #define SWSTAT_SWDONE_ACK_MASK GENMASK_32(1U, 0U) 48a4efd428SKhristine Andreea Barbulescu 49a4efd428SKhristine Andreea Barbulescu #define MSTR_DRAM_MASK GENMASK_32(5U, 0U) 50a4efd428SKhristine Andreea Barbulescu #define MSTR_ACT_RANKS_MASK GENMASK_32(25U, 24U) 51a4efd428SKhristine Andreea Barbulescu #define MSTR_DUAL_RANK_VAL 0x3000000U 52a4efd428SKhristine Andreea Barbulescu #define MSTR_BURST_RDWR_POS 16 53a4efd428SKhristine Andreea Barbulescu #define MSTR_BURST_RDWR_MASK 0xFU 54a4efd428SKhristine Andreea Barbulescu #define DFITMG0_PHY_CLK_POS 15 55a4efd428SKhristine Andreea Barbulescu #define DFITMG0_PHY_CLK_MASK 0x1U 56*a60aeae7SKhristine Andreea Barbulescu #define DRAMTMG2_RD_WR_POS 8 57*a60aeae7SKhristine Andreea Barbulescu #define DRAMTMG2_RD_WR_MASK GENMASK_32(4U, 0U) 58*a60aeae7SKhristine Andreea Barbulescu #define DRAMTMG2_WR_RD_POS 0 59*a60aeae7SKhristine Andreea Barbulescu #define DRAMTMG2_WR_RD_MASK GENMASK_32(4U, 0U) 60*a60aeae7SKhristine Andreea Barbulescu #define INIT6_MR5_MASK 0xFFFFU 61*a60aeae7SKhristine Andreea Barbulescu #define INIT7_MR6_MASK 0xFFFFU 62*a60aeae7SKhristine Andreea Barbulescu #define DFITMG1_WRDATA_DELAY_POS 16 63*a60aeae7SKhristine Andreea Barbulescu #define DFITMG1_WRDATA_DELAY_MASK GENMASK_32(4U, 0U) 64*a60aeae7SKhristine Andreea Barbulescu #define RANKCTL_RD_GAP_POS 4 65*a60aeae7SKhristine Andreea Barbulescu #define RANKCTL_RD_GAP_MASK GENMASK_32(3U, 0U) 66*a60aeae7SKhristine Andreea Barbulescu #define RANKCTL_WR_GAP_POS 8 67*a60aeae7SKhristine Andreea Barbulescu #define RANKCTL_WR_GAP_MASK GENMASK_32(3U, 0U) 68a4efd428SKhristine Andreea Barbulescu 69a4efd428SKhristine Andreea Barbulescu #define DDR_SS_AXI_PARITY_ENABLE_MASK GENMASK_32(12U, 4U) 70a4efd428SKhristine Andreea Barbulescu #define DDR_SS_AXI_PARITY_TYPE_MASK GENMASK_32(24U, 16U) 71a4efd428SKhristine Andreea Barbulescu #define DDR_SS_DFI_1_ENABLED 0x1U 72a4efd428SKhristine Andreea Barbulescu #define DBG1_DISABLE_DE_QUEUEING 0x0U 73a4efd428SKhristine Andreea Barbulescu #define RFSHCTL3_DISABLE_AUTO_REFRESH 0x1U 74*a60aeae7SKhristine Andreea Barbulescu #define ENABLE_AXI_PORT 0x000000001 75a4efd428SKhristine Andreea Barbulescu 76a4efd428SKhristine Andreea Barbulescu #define PWRCTL_POWER_DOWN_ENABLE_MASK BIT_32(1) 77a4efd428SKhristine Andreea Barbulescu #define PWRCTL_SELF_REFRESH_ENABLE_MASK BIT_32(0) 78a4efd428SKhristine Andreea Barbulescu #define PWRCTL_EN_DFI_DRAM_CLOCK_DIS_MASK BIT_32(3) 79a4efd428SKhristine Andreea Barbulescu #define DFIMISC_DFI_INIT_COMPLETE_EN_MASK BIT_32(0) 80a4efd428SKhristine Andreea Barbulescu 81*a60aeae7SKhristine Andreea Barbulescu #define MASTER0_CAL_ACTIVE 0x1U 82*a60aeae7SKhristine Andreea Barbulescu #define MASTER0_CAL_DONE 0x0U 83*a60aeae7SKhristine Andreea Barbulescu #define DFIMISC_DFI_INIT_START_MASK BIT_32(5) 84*a60aeae7SKhristine Andreea Barbulescu #define DFISTAT_DFI_INIT_DONE 0x1U 85*a60aeae7SKhristine Andreea Barbulescu #define DFISTAT_DFI_INIT_INCOMPLETE 0x0U 86*a60aeae7SKhristine Andreea Barbulescu #define PWRCTL_SELFREF_SW_MASK BIT_32(5) 87*a60aeae7SKhristine Andreea Barbulescu #define STAT_OPERATING_MODE_MASK GENMASK_32(2U, 0U) 88*a60aeae7SKhristine Andreea Barbulescu #define STAT_OPERATING_MODE_INIT 0x0U 89*a60aeae7SKhristine Andreea Barbulescu #define RFSHCTL3_DIS_AUTO_REFRESH_MASK BIT_32(0) 9030c8a20dSKhristine Andreea Barbulescu #define TRAINING_OK_MSG 0x07U 9130c8a20dSKhristine Andreea Barbulescu #define TRAINING_FAILED_MSG 0xFFU 9230c8a20dSKhristine Andreea Barbulescu 9330c8a20dSKhristine Andreea Barbulescu #define APBONLY_DCTWRITEPROT_ACK_EN 0U 9430c8a20dSKhristine Andreea Barbulescu #define APBONLY_DCTWRITEPROT_ACK_DIS 1U 9530c8a20dSKhristine Andreea Barbulescu 96*a60aeae7SKhristine Andreea Barbulescu #define ADJUST_DDRC_DISABLED 0x0U 97*a60aeae7SKhristine Andreea Barbulescu 98*a60aeae7SKhristine Andreea Barbulescu /* uMCTL2 Multi-Port Registers */ 99*a60aeae7SKhristine Andreea Barbulescu #define DDRC_UMCTL2_MP_BASE 0x403C03F8U 100*a60aeae7SKhristine Andreea Barbulescu #define OFFSET_DDRC_PCTRL_0 0x98U 101*a60aeae7SKhristine Andreea Barbulescu #define OFFSET_DDRC_PCTRL_1 0x148U 102*a60aeae7SKhristine Andreea Barbulescu #define OFFSET_DDRC_PCTRL_2 0x1F8U 103*a60aeae7SKhristine Andreea Barbulescu 10430c8a20dSKhristine Andreea Barbulescu /* PHY related */ 105*a60aeae7SKhristine Andreea Barbulescu #define DDR_PHYA_MASTER0_CALBUSY 0x4038165CU 10630c8a20dSKhristine Andreea Barbulescu #define DDR_PHYA_APBONLY_UCTSHADOWREGS 0x40380404U 10730c8a20dSKhristine Andreea Barbulescu #define UCT_WRITE_PROT_SHADOW_MASK 0x1U 10830c8a20dSKhristine Andreea Barbulescu #define DDR_PHYA_DCTWRITEPROT 0x4038040CU 10930c8a20dSKhristine Andreea Barbulescu #define DDR_PHYA_APBONLY_UCTWRITEONLYSHADOW 0x40380410U 110a4efd428SKhristine Andreea Barbulescu #define OFFSET_DDRC_RFSHCTL3 0x60U 11130c8a20dSKhristine Andreea Barbulescu #define UCT_WRITE_PROT_SHADOW_ACK 0x0U 112a4efd428SKhristine Andreea Barbulescu #define TXDQDLY_COARSE 6U 113a4efd428SKhristine Andreea Barbulescu #define DDRPHY_PIPE_DFI_MISC 1U 114a4efd428SKhristine Andreea Barbulescu #define ARDPTR_INITVAL_ADDR 0x40381494U 115a4efd428SKhristine Andreea Barbulescu 116a4efd428SKhristine Andreea Barbulescu #define CDD_CHA_RR_1_0 0x403B004CU 117a4efd428SKhristine Andreea Barbulescu #define CDD_CHA_RR_0_1 0x403B004DU 118a4efd428SKhristine Andreea Barbulescu #define CDD_CHA_RW_1_1 0x403B0050U 119a4efd428SKhristine Andreea Barbulescu #define CDD_CHA_RW_1_0 0x403B0051U 120a4efd428SKhristine Andreea Barbulescu #define CDD_CHA_RW_0_1 0x403B0054U 121a4efd428SKhristine Andreea Barbulescu #define CDD_CHA_RW_0_0 0x403B0055U 122a4efd428SKhristine Andreea Barbulescu #define CDD_CHA_WR_1_1 0x403B0058U 123a4efd428SKhristine Andreea Barbulescu #define CDD_CHA_WR_1_0 0x403B0059U 124a4efd428SKhristine Andreea Barbulescu #define CDD_CHA_WR_0_1 0x403B005CU 125a4efd428SKhristine Andreea Barbulescu #define CDD_CHA_WR_0_0 0x403B005DU 126a4efd428SKhristine Andreea Barbulescu #define CDD_CHA_WW_1_0 0x403B0060U 127a4efd428SKhristine Andreea Barbulescu #define CDD_CHA_WW_0_1 0x403B0061U 128a4efd428SKhristine Andreea Barbulescu 129a4efd428SKhristine Andreea Barbulescu #define CDD_CHB_RR_1_0 0x403B00B1U 130a4efd428SKhristine Andreea Barbulescu #define CDD_CHB_RR_0_1 0x403B00B4U 131a4efd428SKhristine Andreea Barbulescu #define CDD_CHB_RW_1_1 0x403B00B5U 132a4efd428SKhristine Andreea Barbulescu #define CDD_CHB_RW_1_0 0x403B00B8U 133a4efd428SKhristine Andreea Barbulescu #define CDD_CHB_RW_0_1 0x403B00B9U 134a4efd428SKhristine Andreea Barbulescu #define CDD_CHB_RW_0_0 0x403B00BCU 135a4efd428SKhristine Andreea Barbulescu #define CDD_CHB_WR_1_1 0x403B00BDU 136a4efd428SKhristine Andreea Barbulescu #define CDD_CHB_WR_1_0 0x403B00C0U 137a4efd428SKhristine Andreea Barbulescu #define CDD_CHB_WR_0_1 0x403B00C1U 138a4efd428SKhristine Andreea Barbulescu #define CDD_CHB_WR_0_0 0x403B00C4U 139a4efd428SKhristine Andreea Barbulescu #define CDD_CHB_WW_1_0 0x403B00C5U 140a4efd428SKhristine Andreea Barbulescu #define CDD_CHB_WW_0_1 0x403B00C8U 141a4efd428SKhristine Andreea Barbulescu 142a4efd428SKhristine Andreea Barbulescu #define CDD_CHA_RR_1_0_DDR3 0x403B0059U 143a4efd428SKhristine Andreea Barbulescu #define CDD_CHA_RR_0_1_DDR3 0x403B0060U 144a4efd428SKhristine Andreea Barbulescu #define CDD_CHA_RW_1_1_DDR3 0x403B008DU 145a4efd428SKhristine Andreea Barbulescu #define CDD_CHA_RW_1_0_DDR3 0x403B0090U 146a4efd428SKhristine Andreea Barbulescu #define CDD_CHA_RW_0_1_DDR3 0x403B0095U 147a4efd428SKhristine Andreea Barbulescu #define CDD_CHA_RW_0_0_DDR3 0x403B0098U 148a4efd428SKhristine Andreea Barbulescu #define CDD_CHA_WR_1_1_DDR3 0x403B00ADU 149a4efd428SKhristine Andreea Barbulescu #define CDD_CHA_WR_1_0_DDR3 0x403B00B0U 150a4efd428SKhristine Andreea Barbulescu #define CDD_CHA_WR_0_1_DDR3 0x403B00B5U 151a4efd428SKhristine Andreea Barbulescu #define CDD_CHA_WR_0_0_DDR3 0x403B00B8U 152a4efd428SKhristine Andreea Barbulescu #define CDD_CHA_WW_1_0_DDR3 0x403B0071U 153a4efd428SKhristine Andreea Barbulescu #define CDD_CHA_WW_0_1_DDR3 0x403B0078U 154a4efd428SKhristine Andreea Barbulescu 155a4efd428SKhristine Andreea Barbulescu #define DBYTE0_TXDQSDLYTG0_U0 0x40394B4CU 156a4efd428SKhristine Andreea Barbulescu #define DBYTE0_TXDQSDLYTG0_U1 0x40394B50U 157a4efd428SKhristine Andreea Barbulescu #define DBYTE1_TXDQSDLYTG0_U0 0x40396B4CU 158a4efd428SKhristine Andreea Barbulescu #define DBYTE1_TXDQSDLYTG0_U1 0x40396B50U 159a4efd428SKhristine Andreea Barbulescu #define DBYTE2_TXDQSDLYTG0_U0 0x40398B4CU 160a4efd428SKhristine Andreea Barbulescu #define DBYTE2_TXDQSDLYTG0_U1 0x40398B50U 161a4efd428SKhristine Andreea Barbulescu #define DBYTE3_TXDQSDLYTG0_U0 0x4039AB4CU 162a4efd428SKhristine Andreea Barbulescu #define DBYTE3_TXDQSDLYTG0_U1 0x4039AB50U 163a4efd428SKhristine Andreea Barbulescu 164a4efd428SKhristine Andreea Barbulescu #define DBYTE0_TXDQSDLYTG1_U0 0x40394B6CU 165a4efd428SKhristine Andreea Barbulescu #define DBYTE0_TXDQSDLYTG1_U1 0x40394B70U 166a4efd428SKhristine Andreea Barbulescu #define DBYTE1_TXDQSDLYTG1_U0 0x40396B6CU 167a4efd428SKhristine Andreea Barbulescu #define DBYTE1_TXDQSDLYTG1_U1 0x40396B70U 168a4efd428SKhristine Andreea Barbulescu #define DBYTE2_TXDQSDLYTG1_U0 0x40398B6CU 169a4efd428SKhristine Andreea Barbulescu #define DBYTE2_TXDQSDLYTG1_U1 0x40398B70U 170a4efd428SKhristine Andreea Barbulescu #define DBYTE3_TXDQSDLYTG1_U0 0x4039AB6CU 171a4efd428SKhristine Andreea Barbulescu #define DBYTE3_TXDQSDLYTG1_U1 0x4039AB70U 172a4efd428SKhristine Andreea Barbulescu 173a4efd428SKhristine Andreea Barbulescu #define VREF_CA_A0 0x403B0095U 174a4efd428SKhristine Andreea Barbulescu #define VREF_CA_A1 0x403B0098U 175a4efd428SKhristine Andreea Barbulescu #define VREF_CA_B0 0x403B00FCU 176a4efd428SKhristine Andreea Barbulescu #define VREF_CA_B1 0x403B00FDU 177a4efd428SKhristine Andreea Barbulescu 178a4efd428SKhristine Andreea Barbulescu #define VREF_DQ_A0 0x403B0099U 179a4efd428SKhristine Andreea Barbulescu #define VREF_DQ_A1 0x403B009CU 180a4efd428SKhristine Andreea Barbulescu #define VREF_DQ_B0 0x403B0100U 181a4efd428SKhristine Andreea Barbulescu #define VREF_DQ_B1 0x403B0101U 182a4efd428SKhristine Andreea Barbulescu 183*a60aeae7SKhristine Andreea Barbulescu #define ADJUST_DDRC_MASK BIT_32(2) 184*a60aeae7SKhristine Andreea Barbulescu #define SELFREF_TYPE_MASK GENMASK_32(5U, 4U) 185*a60aeae7SKhristine Andreea Barbulescu 186a4efd428SKhristine Andreea Barbulescu /* DDR Subsystem */ 187a4efd428SKhristine Andreea Barbulescu #define DDR_SS_REG 0x403D0000U 18830c8a20dSKhristine Andreea Barbulescu 18930c8a20dSKhristine Andreea Barbulescu /* Default timeout for DDR PHY operations */ 19030c8a20dSKhristine Andreea Barbulescu #define DEFAULT_TIMEOUT_US 1000000U 19130c8a20dSKhristine Andreea Barbulescu 19247f0a591SKhristine Andreea Barbulescu /* Start addresses of IMEM and DMEM memory areas */ 19347f0a591SKhristine Andreea Barbulescu #define IMEM_START_ADDR 0x403A0000U 19447f0a591SKhristine Andreea Barbulescu #define DMEM_START_ADDR 0x403B0000U 19547f0a591SKhristine Andreea Barbulescu 196*a60aeae7SKhristine Andreea Barbulescu #define OFFSET_DFIPHYMSTR 0x1C4U 197*a60aeae7SKhristine Andreea Barbulescu #define DFIPHYMSTR_ENABLE 0x1U 198*a60aeae7SKhristine Andreea Barbulescu #define DFIPHYMSTR_DISABLED 0x0U 199*a60aeae7SKhristine Andreea Barbulescu #define SELFREF_TYPE_POS 4 200*a60aeae7SKhristine Andreea Barbulescu #define PHY_MASTER_REQUEST 0x1U 201*a60aeae7SKhristine Andreea Barbulescu 202a4efd428SKhristine Andreea Barbulescu struct cdd_type { 203a4efd428SKhristine Andreea Barbulescu uint8_t rr; 204a4efd428SKhristine Andreea Barbulescu uint8_t rw; 205a4efd428SKhristine Andreea Barbulescu uint8_t wr; 206a4efd428SKhristine Andreea Barbulescu uint8_t ww; 207a4efd428SKhristine Andreea Barbulescu }; 208a4efd428SKhristine Andreea Barbulescu 209a4efd428SKhristine Andreea Barbulescu struct space_timing_params { 210a4efd428SKhristine Andreea Barbulescu struct cdd_type cdd; 211a4efd428SKhristine Andreea Barbulescu uint8_t vref_ca; 212a4efd428SKhristine Andreea Barbulescu uint8_t vref_dq; 213a4efd428SKhristine Andreea Barbulescu uint16_t tphy_wrdata_delay; 214a4efd428SKhristine Andreea Barbulescu }; 215a4efd428SKhristine Andreea Barbulescu 216*a60aeae7SKhristine Andreea Barbulescu /* 217*a60aeae7SKhristine Andreea Barbulescu * Post PHY train setup - complementary settings 218*a60aeae7SKhristine Andreea Barbulescu * that needs to be performed after running the firmware. 219*a60aeae7SKhristine Andreea Barbulescu * @param options - various flags controlling post training actions 220*a60aeae7SKhristine Andreea Barbulescu */ 221*a60aeae7SKhristine Andreea Barbulescu uint32_t post_train_setup(uint8_t options); 222*a60aeae7SKhristine Andreea Barbulescu 22330c8a20dSKhristine Andreea Barbulescu /* Wait until firmware finishes execution and return training result */ 22430c8a20dSKhristine Andreea Barbulescu uint32_t wait_firmware_execution(void); 22530c8a20dSKhristine Andreea Barbulescu 226a4efd428SKhristine Andreea Barbulescu /* Set default AXI parity. */ 227a4efd428SKhristine Andreea Barbulescu uint32_t set_axi_parity(void); 228a4efd428SKhristine Andreea Barbulescu 229a4efd428SKhristine Andreea Barbulescu /* Modify bitfield value with delta, given bitfield position and mask */ 230a4efd428SKhristine Andreea Barbulescu bool update_bf(uint32_t *v, uint8_t pos, uint32_t mask, int32_t delta); 231a4efd428SKhristine Andreea Barbulescu 232a4efd428SKhristine Andreea Barbulescu /* Read Critical Delay Differences from message block and store max values */ 233a4efd428SKhristine Andreea Barbulescu void read_cdds(void); 234a4efd428SKhristine Andreea Barbulescu 235a4efd428SKhristine Andreea Barbulescu /* Read trained VrefCA from message block and store average value */ 236a4efd428SKhristine Andreea Barbulescu void read_vref_ca(void); 237a4efd428SKhristine Andreea Barbulescu 238a4efd428SKhristine Andreea Barbulescu /* Read trained VrefDQ from message block and store average value */ 239a4efd428SKhristine Andreea Barbulescu void read_vref_dq(void); 240a4efd428SKhristine Andreea Barbulescu 241a4efd428SKhristine Andreea Barbulescu /* Calculate DFITMG1.dfi_t_wrdata_delay */ 242a4efd428SKhristine Andreea Barbulescu void compute_tphy_wrdata_delay(void); 243a4efd428SKhristine Andreea Barbulescu 24430c8a20dSKhristine Andreea Barbulescu #endif /* DDR_UTILS_H */ 245