1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright 2018 NXP
4  */
5 
6 #include <common.h>
7 #include <errno.h>
8 #include <log.h>
9 #include <asm/io.h>
10 #include <asm/arch/ddr.h>
11 #include <asm/arch/clock.h>
12 #include <asm/arch/ddr.h>
13 #include <asm/arch/sys_proto.h>
14 
poll_pmu_message_ready(void)15 static inline void poll_pmu_message_ready(void)
16 {
17 	unsigned int reg;
18 
19 	do {
20 		reg = reg32_read(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + ddrphy_addr_remap(0xd0004));
21 	} while (reg & 0x1);
22 }
23 
ack_pmu_message_receive(void)24 static inline void ack_pmu_message_receive(void)
25 {
26 	unsigned int reg;
27 
28 	reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + ddrphy_addr_remap(0xd0031), 0x0);
29 
30 	do {
31 		reg = reg32_read(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + ddrphy_addr_remap(0xd0004));
32 	} while (!(reg & 0x1));
33 
34 	reg32_write(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + ddrphy_addr_remap(0xd0031), 0x1);
35 }
36 
get_mail(void)37 static inline unsigned int get_mail(void)
38 {
39 	unsigned int reg;
40 
41 	poll_pmu_message_ready();
42 
43 	reg = reg32_read(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + ddrphy_addr_remap(0xd0032));
44 
45 	ack_pmu_message_receive();
46 
47 	return reg;
48 }
49 
get_stream_message(void)50 static inline unsigned int get_stream_message(void)
51 {
52 	unsigned int reg, reg2;
53 
54 	poll_pmu_message_ready();
55 
56 	reg = reg32_read(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + ddrphy_addr_remap(0xd0032));
57 
58 	reg2 = reg32_read(IP2APB_DDRPHY_IPS_BASE_ADDR(0) + ddrphy_addr_remap(0xd0034));
59 
60 	reg2 = (reg2 << 16) | reg;
61 
62 	ack_pmu_message_receive();
63 
64 	return reg2;
65 }
66 
decode_major_message(unsigned int mail)67 static inline void decode_major_message(unsigned int mail)
68 {
69 	debug("[PMU Major message = 0x%08x]\n", mail);
70 }
71 
decode_streaming_message(void)72 static inline void decode_streaming_message(void)
73 {
74 	unsigned int string_index, arg __maybe_unused;
75 	int i = 0;
76 
77 	string_index = get_stream_message();
78 	debug("PMU String index = 0x%08x\n", string_index);
79 	while (i < (string_index & 0xffff)) {
80 		arg = get_stream_message();
81 		debug("arg[%d] = 0x%08x\n", i, arg);
82 		i++;
83 	}
84 
85 	debug("\n");
86 }
87 
wait_ddrphy_training_complete(void)88 int wait_ddrphy_training_complete(void)
89 {
90 	unsigned int mail;
91 
92 	while (1) {
93 		mail = get_mail();
94 		decode_major_message(mail);
95 		if (mail == 0x08) {
96 			decode_streaming_message();
97 		} else if (mail == 0x07) {
98 			debug("Training PASS\n");
99 			return 0;
100 		} else if (mail == 0xff) {
101 			printf("Training FAILED\n");
102 			return -1;
103 		}
104 	}
105 }
106 
ddrphy_init_set_dfi_clk(unsigned int drate)107 void ddrphy_init_set_dfi_clk(unsigned int drate)
108 {
109 	switch (drate) {
110 	case 4000:
111 		dram_pll_init(MHZ(1000));
112 		dram_disable_bypass();
113 		break;
114 	case 3733:
115 	case 3732:
116 		dram_pll_init(MHZ(933));
117 		dram_disable_bypass();
118 		break;
119 	case 3200:
120 		dram_pll_init(MHZ(800));
121 		dram_disable_bypass();
122 		break;
123 	case 3000:
124 		dram_pll_init(MHZ(750));
125 		dram_disable_bypass();
126 		break;
127 	case 2800:
128 		dram_pll_init(MHZ(700));
129 		dram_disable_bypass();
130 		break;
131 	case 2400:
132 		dram_pll_init(MHZ(600));
133 		dram_disable_bypass();
134 		break;
135 	case 1866:
136 		dram_pll_init(MHZ(466));
137 		dram_disable_bypass();
138 		break;
139 	case 1600:
140 		dram_pll_init(MHZ(400));
141 		dram_disable_bypass();
142 		break;
143 	case 1066:
144 		dram_pll_init(MHZ(266));
145 		dram_disable_bypass();
146 		break;
147 	case 667:
148 		dram_pll_init(MHZ(167));
149 		dram_disable_bypass();
150 		break;
151 	case 625:
152 		dram_enable_bypass(MHZ(625));
153 		break;
154 	case 400:
155 		dram_enable_bypass(MHZ(400));
156 		break;
157 	case 333:
158 		dram_enable_bypass(MHZ(333));
159 		break;
160 	case 200:
161 		dram_enable_bypass(MHZ(200));
162 		break;
163 	case 100:
164 		dram_enable_bypass(MHZ(100));
165 		break;
166 	default:
167 		return;
168 	}
169 }
170 
ddrphy_init_read_msg_block(enum fw_type type)171 void ddrphy_init_read_msg_block(enum fw_type type)
172 {
173 }
174