xref: /rk3399_ARM-atf/include/drivers/nxp/ddr/s32cc/ddr_init.h (revision e4731b1cf2a3b8a779944e12bfb94f107df5e6fe)
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