1 /* SPDX-License-Identifier: GPL-2.0+ */
2 /*
3  * Copyright 2022 NXP
4  */
5 
6 #ifndef __ASM_ARCH_IMX8M_DDR_H
7 #define __ASM_ARCH_IMX8M_DDR_H
8 
9 #include <asm/io.h>
10 #include <asm/types.h>
11 
12 #define DDR_CTL_BASE			0x4E300000
13 #define DDR_PHY_BASE			0x4E100000
14 #define DDRMIX_BLK_CTRL_BASE		0x4E010000
15 
16 #define REG_DDR_SDRAM_MD_CNTL	(DDR_CTL_BASE + 0x120)
17 #define REG_DDR_CS0_BNDS        (DDR_CTL_BASE + 0x0)
18 #define REG_DDR_CS1_BNDS        (DDR_CTL_BASE + 0x8)
19 #define REG_DDRDSR_2			(DDR_CTL_BASE + 0xB24)
20 #define REG_DDR_TIMING_CFG_0	(DDR_CTL_BASE + 0x104)
21 #define REG_DDR_SDRAM_CFG		(DDR_CTL_BASE + 0x110)
22 #define REG_DDR_TIMING_CFG_4	(DDR_CTL_BASE + 0x160)
23 #define REG_DDR_DEBUG_19		(DDR_CTL_BASE + 0xF48)
24 #define REG_DDR_SDRAM_CFG_3	(DDR_CTL_BASE + 0x260)
25 #define REG_DDR_SDRAM_CFG_4	(DDR_CTL_BASE + 0x264)
26 #define REG_DDR_SDRAM_MD_CNTL_2	(DDR_CTL_BASE + 0x270)
27 #define REG_DDR_SDRAM_MPR4	(DDR_CTL_BASE + 0x28C)
28 #define REG_DDR_SDRAM_MPR5	(DDR_CTL_BASE + 0x290)
29 
30 #define REG_DDR_ERR_EN		(DDR_CTL_BASE + 0x1000)
31 
32 #define SRC_BASE_ADDR			(0x44460000)
33 #define SRC_DPHY_BASE_ADDR		(SRC_BASE_ADDR + 0x1400)
34 #define REG_SRC_DPHY_SW_CTRL		(SRC_DPHY_BASE_ADDR + 0x20)
35 #define REG_SRC_DPHY_SINGLE_RESET_SW_CTRL	(SRC_DPHY_BASE_ADDR + 0x24)
36 
37 #define IP2APB_DDRPHY_IPS_BASE_ADDR(X)	(DDR_PHY_BASE + ((X) * 0x2000000))
38 #define DDRPHY_MEM(X)			(DDR_PHY_BASE + ((X) * 0x2000000) + 0x50000)
39 
40 /* PHY State */
41 enum pstate {
42 	PS0,
43 	PS1,
44 	PS2,
45 	PS3,
46 };
47 
48 enum msg_response {
49 	TRAIN_SUCCESS = 0x7,
50 	TRAIN_STREAM_START = 0x8,
51 	TRAIN_FAIL = 0xff,
52 };
53 
54 /* user data type */
55 enum fw_type {
56 	FW_1D_IMAGE,
57 	FW_2D_IMAGE,
58 };
59 
60 struct dram_cfg_param {
61 	unsigned int reg;
62 	unsigned int val;
63 };
64 
65 struct dram_fsp_cfg {
66 	struct dram_cfg_param ddrc_cfg[20];
67 	struct dram_cfg_param mr_cfg[10];
68 	unsigned int bypass;
69 };
70 
71 struct dram_fsp_msg {
72 	unsigned int drate;
73 	enum fw_type fw_type;
74 	struct dram_cfg_param *fsp_cfg;
75 	unsigned int fsp_cfg_num;
76 };
77 
78 struct dram_timing_info {
79 	/* umctl2 config */
80 	struct dram_cfg_param *ddrc_cfg;
81 	unsigned int ddrc_cfg_num;
82 	/* fsp config */
83 	struct dram_fsp_cfg *fsp_cfg;
84 	unsigned int fsp_cfg_num;
85 	/* ddrphy config */
86 	struct dram_cfg_param *ddrphy_cfg;
87 	unsigned int ddrphy_cfg_num;
88 	/* ddr fsp train info */
89 	struct dram_fsp_msg *fsp_msg;
90 	unsigned int fsp_msg_num;
91 	/* ddr phy trained CSR */
92 	struct dram_cfg_param *ddrphy_trained_csr;
93 	unsigned int ddrphy_trained_csr_num;
94 	/* ddr phy PIE */
95 	struct dram_cfg_param *ddrphy_pie;
96 	unsigned int ddrphy_pie_num;
97 	/* initialized drate table */
98 	unsigned int fsp_table[4];
99 };
100 
101 extern struct dram_timing_info dram_timing;
102 
103 void ddr_load_train_firmware(enum fw_type type);
104 int ddr_init(struct dram_timing_info *timing_info);
105 int ddr_cfg_phy(struct dram_timing_info *timing_info);
106 void load_lpddr4_phy_pie(void);
107 void ddrphy_trained_csr_save(struct dram_cfg_param *param, unsigned int num);
108 void *dram_config_save(struct dram_timing_info *info, unsigned long base);
109 void board_dram_ecc_scrub(void);
110 void ddrc_inline_ecc_scrub(unsigned int start_address,
111 			   unsigned int range_address);
112 void ddrc_inline_ecc_scrub_end(unsigned int start_address,
113 			       unsigned int range_address);
114 
115 /* utils function for ddr phy training */
116 int wait_ddrphy_training_complete(void);
117 void ddrphy_init_set_dfi_clk(unsigned int drate);
118 void ddrphy_init_read_msg_block(enum fw_type type);
119 
120 void get_trained_CDD(unsigned int fsp);
121 
122 ulong ddrphy_addr_remap(u32 paddr_apb_from_ctlr);
123 
reg32_write(unsigned long addr,u32 val)124 static inline void reg32_write(unsigned long addr, u32 val)
125 {
126 	writel(val, addr);
127 }
128 
reg32_read(unsigned long addr)129 static inline u32 reg32_read(unsigned long addr)
130 {
131 	return readl(addr);
132 }
133 
reg32setbit(unsigned long addr,u32 bit)134 static inline void reg32setbit(unsigned long addr, u32 bit)
135 {
136 	setbits_le32(addr, (1 << bit));
137 }
138 
139 #define dwc_ddrphy_apb_wr(addr, data) \
140 	reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + ddrphy_addr_remap(addr), data)
141 #define dwc_ddrphy_apb_rd(addr) \
142 	reg32_read(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + ddrphy_addr_remap(addr))
143 
144 extern struct dram_cfg_param ddrphy_trained_csr[];
145 extern u32 ddrphy_trained_csr_num;
146 
147 #endif
148