1a4efd428SKhristine Andreea Barbulescu /*
2*54239065SKhristine Andreea Barbulescu * Copyright 2020-2022,2025-2026 NXP
3a4efd428SKhristine Andreea Barbulescu *
4a4efd428SKhristine Andreea Barbulescu * SPDX-License-Identifier: BSD-3-Clause
5a4efd428SKhristine Andreea Barbulescu */
6a4efd428SKhristine Andreea Barbulescu
7a4efd428SKhristine Andreea Barbulescu #ifndef DDR_INIT_H
8a4efd428SKhristine Andreea Barbulescu #define DDR_INIT_H
9a4efd428SKhristine Andreea Barbulescu
10a4efd428SKhristine Andreea Barbulescu #include <stdlib.h>
11a4efd428SKhristine Andreea Barbulescu #include <string.h>
12a4efd428SKhristine Andreea Barbulescu #include "ddr_utils.h"
13a4efd428SKhristine Andreea Barbulescu
14a4efd428SKhristine Andreea Barbulescu #define APBONLY_MICRORESET 0x40380420U
15a4efd428SKhristine Andreea Barbulescu #define MASTER_PLLCTRL1 0x403816F0U
16a4efd428SKhristine Andreea Barbulescu #define MASTER_PLLTESTMODE 0x40381708U
17a4efd428SKhristine Andreea Barbulescu #define MASTER_PLLCTRL4 0x4038171CU
18a4efd428SKhristine Andreea Barbulescu #define MASTER_PLLCTRL2 0x403816DCU
19a4efd428SKhristine Andreea Barbulescu
20a4efd428SKhristine Andreea Barbulescu #define MASTER_CALOFFSET 0x40381514U
21a4efd428SKhristine Andreea Barbulescu #define MASTER_CALMISC2 0x40381660U
22a4efd428SKhristine Andreea Barbulescu
23a4efd428SKhristine Andreea Barbulescu #define CALDRV 0x9U
24a4efd428SKhristine Andreea Barbulescu #define CALDRV_OFFSET 0x6U
25a4efd428SKhristine Andreea Barbulescu #define CALDRV2_OFFSET 0xAU
26a4efd428SKhristine Andreea Barbulescu #define CALDRV_MASK 0x3FC0U
27a4efd428SKhristine Andreea Barbulescu
28a4efd428SKhristine Andreea Barbulescu #define CALMISC2 0x1U
29a4efd428SKhristine Andreea Barbulescu #define CALMISC2_OFFSET 0xDU
30a4efd428SKhristine Andreea Barbulescu
31*54239065SKhristine Andreea Barbulescu #define MICROCONT_MUX_SEL 0x40380400U
32*54239065SKhristine Andreea Barbulescu #define LOCK_CSR_ACCESS 0x00000001U
33*54239065SKhristine Andreea Barbulescu #define UNLOCK_CSR_ACCESS 0x00000000U
34*54239065SKhristine Andreea Barbulescu
35*54239065SKhristine Andreea Barbulescu #define APBONLY_RESET_TO_MICRO_MASK 0x00000008U
36*54239065SKhristine Andreea Barbulescu #define APBONLY_STALL_TO_MICRO_MASK 0x00000001U
37*54239065SKhristine Andreea Barbulescu #define APBONLY_RESET_STALL_MASK APBONLY_RESET_TO_MICRO_MASK | \
38*54239065SKhristine Andreea Barbulescu APBONLY_STALL_TO_MICRO_MASK
39*54239065SKhristine Andreea Barbulescu #define APBONLY_MICRORESET_CLR_MASK 0x00000000U
40*54239065SKhristine Andreea Barbulescu
41a4efd428SKhristine Andreea Barbulescu #define PLLCTRL1_VALUE 0x00000021U
42a4efd428SKhristine Andreea Barbulescu #define PLLTESTMODE_VALUE 0x00000024U
43a4efd428SKhristine Andreea Barbulescu #define PLLCTRL4_VALUE 0x0000017FU
44a4efd428SKhristine Andreea Barbulescu
pllctrl2_value(uint16_t freq)45a4efd428SKhristine Andreea Barbulescu static inline uint32_t pllctrl2_value(uint16_t freq)
46a4efd428SKhristine Andreea Barbulescu {
47a4efd428SKhristine Andreea Barbulescu if (freq < 469U) {
48a4efd428SKhristine Andreea Barbulescu return 0x7U;
49a4efd428SKhristine Andreea Barbulescu } else if (freq < 625U) {
50a4efd428SKhristine Andreea Barbulescu return 0x6U;
51a4efd428SKhristine Andreea Barbulescu } else if (freq <= 937U) {
52a4efd428SKhristine Andreea Barbulescu return 0xbU;
53a4efd428SKhristine Andreea Barbulescu } else if (freq < 1250U) {
54a4efd428SKhristine Andreea Barbulescu return 0xaU;
55a4efd428SKhristine Andreea Barbulescu } else {
56a4efd428SKhristine Andreea Barbulescu return 0x19U;
57a4efd428SKhristine Andreea Barbulescu }
58a4efd428SKhristine Andreea Barbulescu }
59a4efd428SKhristine Andreea Barbulescu
60*54239065SKhristine Andreea Barbulescu /* Enum for DRAM Type */
61*54239065SKhristine Andreea Barbulescu enum dram_type {
62*54239065SKhristine Andreea Barbulescu DDR3L = 1,
63*54239065SKhristine Andreea Barbulescu LPDDR4
64*54239065SKhristine Andreea Barbulescu };
65*54239065SKhristine Andreea Barbulescu
66*54239065SKhristine Andreea Barbulescu struct regconf {
67*54239065SKhristine Andreea Barbulescu uint32_t addr;
68*54239065SKhristine Andreea Barbulescu uint32_t data;
69*54239065SKhristine Andreea Barbulescu };
70*54239065SKhristine Andreea Barbulescu
71*54239065SKhristine Andreea Barbulescu struct regconf_16 {
72*54239065SKhristine Andreea Barbulescu uint32_t addr;
73*54239065SKhristine Andreea Barbulescu uint16_t data;
74*54239065SKhristine Andreea Barbulescu } __packed;
75*54239065SKhristine Andreea Barbulescu
76*54239065SKhristine Andreea Barbulescu struct dqconf {
77*54239065SKhristine Andreea Barbulescu uint32_t addr;
78*54239065SKhristine Andreea Barbulescu uint8_t data;
79*54239065SKhristine Andreea Barbulescu } __packed;
80*54239065SKhristine Andreea Barbulescu
81*54239065SKhristine Andreea Barbulescu struct ddrss_config {
82*54239065SKhristine Andreea Barbulescu uint8_t memory_type;
83*54239065SKhristine Andreea Barbulescu uint16_t frequency;
84*54239065SKhristine Andreea Barbulescu struct regconf *ddrc;
85*54239065SKhristine Andreea Barbulescu size_t ddrc_size;
86*54239065SKhristine Andreea Barbulescu struct dqconf *dq_swap;
87*54239065SKhristine Andreea Barbulescu size_t dq_swap_size;
88*54239065SKhristine Andreea Barbulescu struct regconf_16 *phy;
89*54239065SKhristine Andreea Barbulescu size_t phy_size;
90*54239065SKhristine Andreea Barbulescu struct regconf_16 *pie;
91*54239065SKhristine Andreea Barbulescu size_t pie_size;
92*54239065SKhristine Andreea Barbulescu uint16_t *imem_1d;
93*54239065SKhristine Andreea Barbulescu size_t imem_1d_size;
94*54239065SKhristine Andreea Barbulescu uint16_t *dmem_1d;
95*54239065SKhristine Andreea Barbulescu size_t dmem_1d_size;
96*54239065SKhristine Andreea Barbulescu uint16_t *imem_2d;
97*54239065SKhristine Andreea Barbulescu size_t imem_2d_size;
98*54239065SKhristine Andreea Barbulescu uint16_t *dmem_2d;
99*54239065SKhristine Andreea Barbulescu size_t dmem_2d_size;
100*54239065SKhristine Andreea Barbulescu uint32_t *phy_csr;
101*54239065SKhristine Andreea Barbulescu size_t phy_csr_size;
102*54239065SKhristine Andreea Barbulescu uint32_t *ddrc_csr;
103*54239065SKhristine Andreea Barbulescu size_t ddrc_csr_size;
104*54239065SKhristine Andreea Barbulescu };
105*54239065SKhristine Andreea Barbulescu
106*54239065SKhristine Andreea Barbulescu struct ddr_fw_header {
107*54239065SKhristine Andreea Barbulescu uint8_t header_version;
108*54239065SKhristine Andreea Barbulescu char ddrt_version[8];
109*54239065SKhristine Andreea Barbulescu char soc_name[16];
110*54239065SKhristine Andreea Barbulescu char fw_version[16];
111*54239065SKhristine Andreea Barbulescu char reserved[23];
112*54239065SKhristine Andreea Barbulescu };
113*54239065SKhristine Andreea Barbulescu
114*54239065SKhristine Andreea Barbulescu struct ddr_fw_layout {
115*54239065SKhristine Andreea Barbulescu uint8_t memory_type;
116*54239065SKhristine Andreea Barbulescu uint16_t frequency;
117*54239065SKhristine Andreea Barbulescu uint16_t ddrc_size;
118*54239065SKhristine Andreea Barbulescu uint16_t dq_swap_size;
119*54239065SKhristine Andreea Barbulescu uint16_t phy_size;
120*54239065SKhristine Andreea Barbulescu uint16_t pie_size;
121*54239065SKhristine Andreea Barbulescu uint16_t imem_1d_size;
122*54239065SKhristine Andreea Barbulescu uint16_t dmem_1d_size;
123*54239065SKhristine Andreea Barbulescu uint16_t imem_2d_size;
124*54239065SKhristine Andreea Barbulescu uint16_t dmem_2d_size;
125*54239065SKhristine Andreea Barbulescu uint16_t phy_csr_size;
126*54239065SKhristine Andreea Barbulescu uint16_t ddrc_csr_size;
127*54239065SKhristine Andreea Barbulescu uint32_t ddrc_offset;
128*54239065SKhristine Andreea Barbulescu uint32_t dq_swap_offset;
129*54239065SKhristine Andreea Barbulescu uint32_t phy_offset;
130*54239065SKhristine Andreea Barbulescu uint32_t pie_offset;
131*54239065SKhristine Andreea Barbulescu uint32_t imem_1d_offset;
132*54239065SKhristine Andreea Barbulescu uint32_t dmem_1d_offset;
133*54239065SKhristine Andreea Barbulescu uint32_t imem_2d_offset;
134*54239065SKhristine Andreea Barbulescu uint32_t dmem_2d_offset;
135*54239065SKhristine Andreea Barbulescu uint32_t phy_csr_offset;
136*54239065SKhristine Andreea Barbulescu uint32_t ddrc_csr_offset;
137*54239065SKhristine Andreea Barbulescu };
138*54239065SKhristine Andreea Barbulescu
139*54239065SKhristine Andreea Barbulescu uint32_t ddr_init_cfg(const struct ddrss_config *config);
140*54239065SKhristine Andreea Barbulescu
141*54239065SKhristine Andreea Barbulescu /*
142*54239065SKhristine Andreea Barbulescu * Writes the data associated for each address.
143*54239065SKhristine Andreea Barbulescu *
144*54239065SKhristine Andreea Barbulescu * @param size - size of the array, number of elements
145*54239065SKhristine Andreea Barbulescu * @param cfg - array of configuration elements
146*54239065SKhristine Andreea Barbulescu * @return - error code, 0 if init succeeds, non-zero on error.
147*54239065SKhristine Andreea Barbulescu */
148*54239065SKhristine Andreea Barbulescu uint32_t load_register_cfg(size_t size, const struct regconf cfg[]);
149*54239065SKhristine Andreea Barbulescu
150*54239065SKhristine Andreea Barbulescu /*
151*54239065SKhristine Andreea Barbulescu * Writes the data associated for each address. Similar to
152*54239065SKhristine Andreea Barbulescu * @load_register_cfg but uses 16bit data elements for memory
153*54239065SKhristine Andreea Barbulescu * usage optimization.
154*54239065SKhristine Andreea Barbulescu *
155*54239065SKhristine Andreea Barbulescu * @param size - size of the array, number of elements
156*54239065SKhristine Andreea Barbulescu * @param cfg - array of configuration elements
157*54239065SKhristine Andreea Barbulescu * @return - error code, 0 if init succeeds, non-zero on error.
158*54239065SKhristine Andreea Barbulescu */
159*54239065SKhristine Andreea Barbulescu uint32_t load_register_cfg_16(size_t size, const struct regconf_16 cfg[]);
160*54239065SKhristine Andreea Barbulescu
161*54239065SKhristine Andreea Barbulescu /*
162*54239065SKhristine Andreea Barbulescu * Writes the data associated for each address. Similar to
163*54239065SKhristine Andreea Barbulescu * @load_register_cfg but uses 8bit data elements for memory
164*54239065SKhristine Andreea Barbulescu * usage optimization.
165*54239065SKhristine Andreea Barbulescu *
166*54239065SKhristine Andreea Barbulescu * @param size - size of the array, number of elements
167*54239065SKhristine Andreea Barbulescu * @param cfg - array of configuration elements
168*54239065SKhristine Andreea Barbulescu * @return - error code, 0 if init succeeds, non-zero on error.
169*54239065SKhristine Andreea Barbulescu */
170*54239065SKhristine Andreea Barbulescu uint32_t load_dq_cfg(size_t size, const struct dqconf cfg[]);
171*54239065SKhristine Andreea Barbulescu
172a4efd428SKhristine Andreea Barbulescu /*
173a4efd428SKhristine Andreea Barbulescu * Updates PHY internal PLL settings.
174a4efd428SKhristine Andreea Barbulescu * @param frequency - selected DDR frequency
175a4efd428SKhristine Andreea Barbulescu */
176a4efd428SKhristine Andreea Barbulescu void set_optimal_pll(uint16_t frequency);
177a4efd428SKhristine Andreea Barbulescu
178a4efd428SKhristine Andreea Barbulescu #endif /* DDR_INIT_H */
179