"Das U-Boot" Source Tree
at master 311 lines 8.6 kB view raw
1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * Copyright (C) 2015 Google, Inc 4 * Written by Simon Glass <sjg@chromium.org> 5 */ 6 7#include <console.h> 8#include <dm.h> 9#include <i2c.h> 10#include <log.h> 11#include <rtc.h> 12#include <asm/io.h> 13#include <asm/rtc.h> 14#include <asm/test.h> 15#include <dm/test.h> 16#include <test/test.h> 17#include <test/ut.h> 18 19/* Simple RTC sanity check */ 20static int dm_test_rtc_base(struct unit_test_state *uts) 21{ 22 struct udevice *dev; 23 24 ut_asserteq(-ENODEV, uclass_get_device_by_seq(UCLASS_RTC, 2, &dev)); 25 ut_assertok(uclass_get_device(UCLASS_RTC, 0, &dev)); 26 ut_assertok(uclass_get_device(UCLASS_RTC, 1, &dev)); 27 28 return 0; 29} 30DM_TEST(dm_test_rtc_base, UTF_SCAN_PDATA | UTF_SCAN_FDT); 31 32static void show_time(const char *msg, struct rtc_time *time) 33{ 34 printf("%s: %02d/%02d/%04d %02d:%02d:%02d\n", msg, 35 time->tm_mday, time->tm_mon, time->tm_year, 36 time->tm_hour, time->tm_min, time->tm_sec); 37} 38 39static int cmp_times(struct rtc_time *expect, struct rtc_time *time, bool show) 40{ 41 bool same; 42 43 same = expect->tm_sec == time->tm_sec; 44 same &= expect->tm_min == time->tm_min; 45 same &= expect->tm_hour == time->tm_hour; 46 same &= expect->tm_mday == time->tm_mday; 47 same &= expect->tm_mon == time->tm_mon; 48 same &= expect->tm_year == time->tm_year; 49 if (!same && show) { 50 show_time("expected", expect); 51 show_time("actual", time); 52 } 53 54 return same ? 0 : -EINVAL; 55} 56 57/* Set and get the time */ 58static int dm_test_rtc_set_get(struct unit_test_state *uts) 59{ 60 struct rtc_time now, time, cmp; 61 struct udevice *dev, *emul; 62 long offset, check_offset, old_offset, old_base_time; 63 int i; 64 65 ut_assertok(uclass_get_device(UCLASS_RTC, 0, &dev)); 66 67 ut_assertok(i2c_emul_find(dev, &emul)); 68 ut_assertnonnull(emul); 69 70 /* Get the offset, putting the RTC into manual mode */ 71 i = 0; 72 do { 73 check_offset = sandbox_i2c_rtc_set_offset(emul, false, 0); 74 ut_assertok(dm_rtc_get(dev, &now)); 75 76 /* Tell the RTC to go into manual mode */ 77 old_offset = sandbox_i2c_rtc_set_offset(emul, false, 0); 78 79 /* If the times changed in that period, read it again */ 80 } while (++i < 2 && check_offset != old_offset); 81 ut_asserteq(check_offset, old_offset); 82 83 old_base_time = sandbox_i2c_rtc_get_set_base_time(emul, -1); 84 85 memset(&time, '\0', sizeof(time)); 86 time.tm_mday = 3; 87 time.tm_mon = 6; 88 time.tm_year = 2004; 89 time.tm_sec = 0; 90 time.tm_min = 18; 91 time.tm_hour = 18; 92 ut_assertok(dm_rtc_set(dev, &time)); 93 94 memset(&cmp, '\0', sizeof(cmp)); 95 ut_assertok(dm_rtc_get(dev, &cmp)); 96 ut_assertok(cmp_times(&time, &cmp, true)); 97 98 memset(&time, '\0', sizeof(time)); 99 time.tm_mday = 31; 100 time.tm_mon = 8; 101 time.tm_year = 2004; 102 time.tm_sec = 0; 103 time.tm_min = 18; 104 time.tm_hour = 18; 105 ut_assertok(dm_rtc_set(dev, &time)); 106 107 memset(&cmp, '\0', sizeof(cmp)); 108 ut_assertok(dm_rtc_get(dev, &cmp)); 109 ut_assertok(cmp_times(&time, &cmp, true)); 110 111 /* Increment by 1 second */ 112 offset = sandbox_i2c_rtc_set_offset(emul, false, 0); 113 sandbox_i2c_rtc_set_offset(emul, false, offset + 1); 114 115 memset(&cmp, '\0', sizeof(cmp)); 116 ut_assertok(dm_rtc_get(dev, &cmp)); 117 ut_asserteq(1, cmp.tm_sec); 118 119 /* Check against original offset */ 120 sandbox_i2c_rtc_set_offset(emul, false, old_offset); 121 ut_assertok(dm_rtc_get(dev, &cmp)); 122 ut_assertok(cmp_times(&now, &cmp, true)); 123 124 /* Back to the original offset */ 125 sandbox_i2c_rtc_set_offset(emul, false, 0); 126 memset(&cmp, '\0', sizeof(cmp)); 127 ut_assertok(dm_rtc_get(dev, &cmp)); 128 ut_assertok(cmp_times(&now, &cmp, true)); 129 130 /* Increment the base time by 1 emul */ 131 sandbox_i2c_rtc_get_set_base_time(emul, old_base_time + 1); 132 memset(&cmp, '\0', sizeof(cmp)); 133 ut_assertok(dm_rtc_get(dev, &cmp)); 134 if (now.tm_sec == 59) { 135 ut_asserteq(0, cmp.tm_sec); 136 } else { 137 ut_asserteq(now.tm_sec + 1, cmp.tm_sec); 138 } 139 140 /* return RTC to normal mode */ 141 sandbox_i2c_rtc_set_offset(emul, true, 0); 142 143 return 0; 144} 145DM_TEST(dm_test_rtc_set_get, UTF_SCAN_PDATA | UTF_SCAN_FDT); 146 147static int dm_test_rtc_read_write(struct unit_test_state *uts) 148{ 149 struct rtc_time time; 150 struct udevice *dev, *emul; 151 long old_offset; 152 u8 buf[4], reg; 153 154 ut_assertok(uclass_get_device(UCLASS_RTC, 0, &dev)); 155 156 memcpy(buf, "car", 4); 157 ut_assertok(dm_rtc_write(dev, REG_AUX0, buf, 4)); 158 memset(buf, '\0', sizeof(buf)); 159 ut_assertok(dm_rtc_read(dev, REG_AUX0, buf, 4)); 160 ut_asserteq(memcmp(buf, "car", 4), 0); 161 162 reg = 'b'; 163 ut_assertok(dm_rtc_write(dev, REG_AUX0, &reg, 1)); 164 memset(buf, '\0', sizeof(buf)); 165 ut_assertok(dm_rtc_read(dev, REG_AUX0, buf, 4)); 166 ut_asserteq(memcmp(buf, "bar", 4), 0); 167 168 reg = 't'; 169 ut_assertok(dm_rtc_write(dev, REG_AUX2, &reg, 1)); 170 memset(buf, '\0', sizeof(buf)); 171 ut_assertok(dm_rtc_read(dev, REG_AUX1, buf, 3)); 172 ut_asserteq(memcmp(buf, "at", 3), 0); 173 174 ut_assertok(i2c_emul_find(dev, &emul)); 175 ut_assertnonnull(emul); 176 177 old_offset = sandbox_i2c_rtc_set_offset(emul, false, 0); 178 ut_assertok(dm_rtc_get(dev, &time)); 179 180 ut_assertok(dm_rtc_read(dev, REG_SEC, &reg, 1)); 181 ut_asserteq(time.tm_sec, reg); 182 ut_assertok(dm_rtc_read(dev, REG_MDAY, &reg, 1)); 183 ut_asserteq(time.tm_mday, reg); 184 185 sandbox_i2c_rtc_set_offset(emul, true, old_offset); 186 187 return 0; 188} 189DM_TEST(dm_test_rtc_read_write, UTF_SCAN_PDATA | UTF_SCAN_FDT); 190 191/* Test 'rtc list' command */ 192static int dm_test_rtc_cmd_list(struct unit_test_state *uts) 193{ 194 run_command("rtc list", 0); 195 ut_assert_nextline("RTC #0 - rtc@43"); 196 ut_assert_nextline("RTC #1 - rtc@61"); 197 ut_assert_console_end(); 198 199 return 0; 200} 201DM_TEST(dm_test_rtc_cmd_list, UTF_SCAN_PDATA | UTF_SCAN_FDT | UTF_CONSOLE); 202 203/* Test 'rtc read' and 'rtc write' commands */ 204static int dm_test_rtc_cmd_rw(struct unit_test_state *uts) 205{ 206 run_command("rtc dev 0", 0); 207 ut_assert_nextline("RTC #0 - rtc@43"); 208 ut_assert_console_end(); 209 210 run_command("rtc write 0x30 aabb", 0); 211 ut_assert_console_end(); 212 213 run_command("rtc read 0x30 2", 0); 214 ut_assert_nextline("00000030: aa bb .."); 215 ut_assert_console_end(); 216 217 run_command("rtc dev 1", 0); 218 ut_assert_nextline("RTC #1 - rtc@61"); 219 ut_assert_console_end(); 220 221 run_command("rtc write 0x30 ccdd", 0); 222 ut_assert_console_end(); 223 224 run_command("rtc read 0x30 2", 0); 225 ut_assert_nextline("00000030: cc dd .."); 226 ut_assert_console_end(); 227 228 /* 229 * Switch back to device #0, check that its aux registers 230 * still have the same values. 231 */ 232 run_command("rtc dev 0", 0); 233 ut_assert_nextline("RTC #0 - rtc@43"); 234 ut_assert_console_end(); 235 236 run_command("rtc read 0x30 2", 0); 237 ut_assert_nextline("00000030: aa bb .."); 238 ut_assert_console_end(); 239 240 return 0; 241} 242DM_TEST(dm_test_rtc_cmd_rw, UTF_SCAN_PDATA | UTF_SCAN_FDT | UTF_CONSOLE); 243 244/* Reset the time */ 245static int dm_test_rtc_reset(struct unit_test_state *uts) 246{ 247 struct rtc_time now; 248 struct udevice *dev, *emul; 249 long old_base_time, base_time; 250 int i; 251 252 ut_assertok(uclass_get_device(UCLASS_RTC, 0, &dev)); 253 ut_assertok(dm_rtc_get(dev, &now)); 254 255 ut_assertok(i2c_emul_find(dev, &emul)); 256 ut_assertnonnull(emul); 257 258 i = 0; 259 do { 260 old_base_time = sandbox_i2c_rtc_get_set_base_time(emul, 0); 261 262 ut_asserteq(0, sandbox_i2c_rtc_get_set_base_time(emul, -1)); 263 264 ut_assertok(dm_rtc_reset(dev)); 265 base_time = sandbox_i2c_rtc_get_set_base_time(emul, -1); 266 267 /* 268 * Resetting the RTC should put the base time back to normal. 269 * Allow for a one-timeadjustment in case the time flips over 270 * while this test process is pre-empted (either by a second 271 * or a daylight-saving change), since reset_time() in 272 * i2c_rtc_emul.c reads the time from the OS. 273 */ 274 } while (++i < 2 && base_time != old_base_time); 275 ut_asserteq(old_base_time, base_time); 276 277 return 0; 278} 279DM_TEST(dm_test_rtc_reset, UTF_SCAN_PDATA | UTF_SCAN_FDT); 280 281/* Check that two RTC devices can be used independently */ 282static int dm_test_rtc_dual(struct unit_test_state *uts) 283{ 284 struct rtc_time now1, now2, cmp; 285 struct udevice *dev1, *dev2; 286 struct udevice *emul1, *emul2; 287 long offset; 288 289 ut_assertok(uclass_get_device(UCLASS_RTC, 0, &dev1)); 290 ut_assertok(dm_rtc_get(dev1, &now1)); 291 ut_assertok(uclass_get_device(UCLASS_RTC, 1, &dev2)); 292 ut_assertok(dm_rtc_get(dev2, &now2)); 293 294 ut_assertok(i2c_emul_find(dev1, &emul1)); 295 ut_assertnonnull(emul1); 296 ut_assertok(i2c_emul_find(dev2, &emul2)); 297 ut_assertnonnull(emul2); 298 299 offset = sandbox_i2c_rtc_set_offset(emul1, false, -1); 300 sandbox_i2c_rtc_set_offset(emul2, false, offset + 1); 301 memset(&cmp, '\0', sizeof(cmp)); 302 ut_assertok(dm_rtc_get(dev2, &cmp)); 303 ut_asserteq(-EINVAL, cmp_times(&now1, &cmp, false)); 304 305 memset(&cmp, '\0', sizeof(cmp)); 306 ut_assertok(dm_rtc_get(dev1, &cmp)); 307 ut_assertok(cmp_times(&now1, &cmp, true)); 308 309 return 0; 310} 311DM_TEST(dm_test_rtc_dual, UTF_SCAN_PDATA | UTF_SCAN_FDT);