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 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 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 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 */ 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 } 88 89 length[max_bank - 1] = (gd->start_addr_sp - RESERVED_SP_SIZE - 90 start_adr[max_bank - 1]) & ~0xfff; 91 if (print_en) { 92 printf("available memory for test:\n"); 93 printf(" start end length\n"); 94 for (i = 0; i < max_bank; i++) 95 if (length[i]) 96 printf(" 0x%08lx - 0x%08lx 0x%08lx\n", 97 start_adr[i], start_adr[i] + length[i], 98 length[i]); 99 } 100 } 101 102 /* 103 * judge if testing address is available 104 * arg[0]:start addr, arg[1]:length, return test banks number 105 */ 106 int judge_test_addr(ulong *arg, ulong *start_adr, ulong *length) 107 { 108 u32 i, max_bank = 0; 109 u32 available = 0; 110 111 for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) 112 if (start_adr[i]) 113 max_bank = i + 1; 114 115 if (!arg[1]) 116 return max_bank; 117 118 for (i = 0; i < max_bank; i++) 119 if (arg[0] >= start_adr[i] && 120 arg[0] + arg[1] <= start_adr[i] + length[i]) 121 available |= 1; 122 if (!available) { 123 printf("Invalid test address\n"); 124 } else { 125 start_adr[0] = arg[0]; 126 length[0] = arg[1]; 127 for (i = 1; i < max_bank; i++) { 128 start_adr[i] = 0; 129 length[i] = 0; 130 } 131 } 132 133 return available; 134 } 135 136 int set_vdd_logic(u32 uv) 137 { 138 struct udevice *dev; 139 int ret; 140 141 ret = regulator_get_by_platname("vdd_logic", &dev); 142 if (ret) { 143 printf("Cannot set regulator name\n"); 144 return ret; 145 } 146 147 /* Slowly raise to max CPU voltage to prevent overshoot */ 148 ret = regulator_set_value(dev, uv); 149 udelay(100); /* Must wait for voltage to stabilize, 2mV/us */ 150 if (ret) 151 printf("set vdd_logic fail\n"); 152 return ret; 153 } 154 155