xref: /OK3568_Linux_fs/u-boot/cmd/ddr_tool/ddr_tool_common.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 // SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
2 /*
3  * (C) Copyright 2019 Rockchip Electronics Co., Ltd.
4  */
5 
6 #include <common.h>
7 #include <power/regulator.h>
8 #include "ddr_tool_common.h"
9 
10 DECLARE_GLOBAL_DATA_PTR;
11 
write_buf_to_ddr(u32 * buf,u32 buf_len,ulong start_adr,ulong length)12 void write_buf_to_ddr(u32 *buf, u32 buf_len, ulong start_adr, ulong length)
13 {
14 	ulong *buful = (ulong *)buf;
15 	ulong *p = (ulong *)start_adr;
16 	u32 i, j;
17 
18 	buf_len = buf_len / sizeof(ulong) - 1;
19 
20 	for (i = 0, j = 0; i < length / sizeof(p[0]); i++) {
21 		p[i] = buful[j];
22 		j++;
23 		j &= buf_len;
24 	}
25 }
26 
cmp_buf_data(u32 * buf,u32 buf_len,ulong start_adr,ulong length,u32 prt_en)27 ulong cmp_buf_data(u32 *buf, u32 buf_len, ulong start_adr, ulong length,
28 		   u32 prt_en)
29 {
30 	ulong *buful = (ulong *)buf;
31 	volatile unsigned long *p = (volatile unsigned long *)start_adr;
32 	u32 i, j;
33 	ulong reread = 0;
34 	ulong wr_val = 0;
35 	ulong val = 0;
36 	ulong err_adr = 0;
37 
38 	buf_len = buf_len / sizeof(ulong) - 1;
39 	err_adr = 0;
40 	for (i = 0, j = 0; i < length / sizeof(p[0]); i++) {
41 		val = p[i];
42 		if (val != buful[j]) {
43 			flush_dcache_range((ulong)&p[i],
44 					   (ulong)&p[i] + sizeof(u32));
45 			reread = p[i];
46 			err_adr = (ulong)&p[i];
47 			wr_val = buful[j];
48 			break;
49 		}
50 		j++;
51 		j &= buf_len;
52 	}
53 	if (err_adr && prt_en)
54 		printf("test fail:address:0x%lx,read:0x%lx,"
55 		       "reread:0x%lx,expect:0x%lx\n",
56 		       err_adr, val, reread, wr_val);
57 
58 	return err_adr;
59 }
60 
print_memory(void * addr,ulong size)61 void print_memory(void *addr, ulong size)
62 {
63 	u32 *p = addr;
64 	u32 i;
65 
66 	for (i = 0; i < size / 4; i += 4) {
67 		printf("0x%08lx: 0x%08x, 0x%08x, 0x%08x, 0x%08x\n",
68 		       (ulong)&p[i], p[i], p[i + 1], p[i + 2], p[i + 3]);
69 	}
70 }
71 
72 /* print available address for ddr testing in uboot */
get_print_available_addr(ulong * start_adr,ulong * length,int print_en)73 void get_print_available_addr(ulong *start_adr, ulong *length, int print_en)
74 {
75 	u32 i, max_bank = 0;
76 
77 	for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
78 		if (gd->bd->bi_dram[i].start)
79 			max_bank = i + 1;
80 		start_adr[i] = 0;
81 		length[i] = 0;
82 	}
83 
84 	for (i = 0; i < max_bank; i++) {
85 		start_adr[i] = gd->bd->bi_dram[i].start;
86 		length[i] = gd->bd->bi_dram[i].size;
87 #if defined(CONFIG_ROCKCHIP_RV1126)
88 		/* On RV1126, writing data to 0x00600000 will cause a crash. */
89 		if (start_adr[i] == 0 && length[i] > 0x00700000) {
90 			start_adr[i] = 0x00700000;
91 			length[i] -= 0x00700000;
92 		}
93 #endif
94 	}
95 
96 	length[max_bank - 1] = (gd->start_addr_sp - RESERVED_SP_SIZE -
97 			start_adr[max_bank - 1]) & ~0xfff;
98 	if (print_en) {
99 		printf("available memory for test:\n");
100 		printf("	start		 end	length\n");
101 		for (i = 0; i < max_bank; i++)
102 			if (length[i])
103 				printf("	0x%08lx - 0x%08lx 0x%08lx\n",
104 				       start_adr[i], start_adr[i] + length[i],
105 				       length[i]);
106 	}
107 }
108 
109 /*
110  * judge if testing address is available
111  * arg[0]:start addr, arg[1]:length, return test banks number
112  */
judge_test_addr(ulong * arg,ulong * start_adr,ulong * length)113 int judge_test_addr(ulong *arg, ulong *start_adr, ulong *length)
114 {
115 	u32 i, max_bank = 0;
116 	u32 available = 0;
117 
118 	for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++)
119 		if (start_adr[i])
120 			max_bank = i + 1;
121 
122 	if (!arg[1])
123 		return max_bank;
124 
125 	for (i = 0; i < max_bank; i++)
126 		if (arg[0] >= start_adr[i] &&
127 		    arg[0] + arg[1] <= start_adr[i] + length[i])
128 			available |= 1;
129 	if (!available) {
130 		printf("Invalid test address\n");
131 	} else {
132 		start_adr[0] = arg[0];
133 		length[0] = arg[1];
134 		for (i = 1; i < max_bank; i++) {
135 			start_adr[i] = 0;
136 			length[i] = 0;
137 		}
138 	}
139 
140 	return available;
141 }
142 
set_vdd_logic(u32 uv)143 int set_vdd_logic(u32 uv)
144 {
145 	struct udevice *dev;
146 	int ret;
147 
148 	ret = regulator_get_by_platname("vdd_logic", &dev);
149 	if (ret) {
150 		printf("Cannot set regulator name\n");
151 		return ret;
152 	}
153 
154 	/* Slowly raise to max CPU voltage to prevent overshoot */
155 	ret = regulator_set_value(dev, uv);
156 	udelay(100); /* Must wait for voltage to stabilize, 2mV/us */
157 	if (ret)
158 		printf("set vdd_logic fail\n");
159 	return ret;
160 }
161 
162