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 #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 */ 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 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