• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (C) 2015 Google, Inc
4  */
5 
6 #include <common.h>
7 #include <dm.h>
8 #include <mapmem.h>
9 #include <regmap.h>
10 #include <syscon.h>
11 #include <asm/test.h>
12 #include <dm/test.h>
13 #include <test/ut.h>
14 
15 /* Base test of register maps */
dm_test_regmap_base(struct unit_test_state * uts)16 static int dm_test_regmap_base(struct unit_test_state *uts)
17 {
18 	struct udevice *dev;
19 	struct regmap *map;
20 	ofnode node;
21 	int i;
22 
23 	ut_assertok(uclass_get_device(UCLASS_SYSCON, 0, &dev));
24 	map = syscon_get_regmap(dev);
25 	ut_assertok_ptr(map);
26 	ut_asserteq(1, map->range_count);
27 	ut_asserteq(0x10, map->ranges[0].start);
28 	ut_asserteq(16, map->ranges[0].size);
29 	ut_asserteq(0x10, map_to_sysmem(regmap_get_range(map, 0)));
30 
31 	ut_assertok(uclass_get_device(UCLASS_SYSCON, 1, &dev));
32 	map = syscon_get_regmap(dev);
33 	ut_assertok_ptr(map);
34 	ut_asserteq(4, map->range_count);
35 	ut_asserteq(0x20, map->ranges[0].start);
36 	for (i = 0; i < 4; i++) {
37 		const unsigned long addr = 0x20 + 8 * i;
38 
39 		ut_asserteq(addr, map->ranges[i].start);
40 		ut_asserteq(5 + i, map->ranges[i].size);
41 		ut_asserteq(addr, map_to_sysmem(regmap_get_range(map, i)));
42 	}
43 
44 	/* Check that we can't pretend a different device is a syscon */
45 	ut_assertok(uclass_get_device(UCLASS_I2C, 0, &dev));
46 	map = syscon_get_regmap(dev);
47 	ut_asserteq_ptr(ERR_PTR(-ENOEXEC), map);
48 
49 	/* A different device can be a syscon by using Linux-compat API */
50 	node = ofnode_path("/syscon@2");
51 	ut_assert(ofnode_valid(node));
52 
53 	map = syscon_node_to_regmap(node);
54 	ut_assertok_ptr(map);
55 	ut_asserteq(4, map->range_count);
56 	ut_asserteq(0x40, map->ranges[0].start);
57 	for (i = 0; i < 4; i++) {
58 		const unsigned long addr = 0x40 + 8 * i;
59 
60 		ut_asserteq(addr, map->ranges[i].start);
61 		ut_asserteq(5 + i, map->ranges[i].size);
62 		ut_asserteq(addr, map_to_sysmem(regmap_get_range(map, i)));
63 	}
64 
65 	return 0;
66 }
67 DM_TEST(dm_test_regmap_base, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
68 
69 /* Test we can access a regmap through syscon */
dm_test_regmap_syscon(struct unit_test_state * uts)70 static int dm_test_regmap_syscon(struct unit_test_state *uts)
71 {
72 	struct regmap *map;
73 
74 	map = syscon_get_regmap_by_driver_data(SYSCON0);
75 	ut_assertok_ptr(map);
76 	ut_asserteq(1, map->range_count);
77 
78 	map = syscon_get_regmap_by_driver_data(SYSCON1);
79 	ut_assertok_ptr(map);
80 	ut_asserteq(4, map->range_count);
81 
82 	map = syscon_get_regmap_by_driver_data(SYSCON_COUNT);
83 	ut_asserteq_ptr(ERR_PTR(-ENODEV), map);
84 
85 	ut_asserteq(0x10, map_to_sysmem(syscon_get_first_range(SYSCON0)));
86 	ut_asserteq(0x20, map_to_sysmem(syscon_get_first_range(SYSCON1)));
87 	ut_asserteq_ptr(ERR_PTR(-ENODEV),
88 			syscon_get_first_range(SYSCON_COUNT));
89 
90 	return 0;
91 }
92 
93 DM_TEST(dm_test_regmap_syscon, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
94 
95 /* Read/Write/Modify test */
dm_test_regmap_rw(struct unit_test_state * uts)96 static int dm_test_regmap_rw(struct unit_test_state *uts)
97 {
98 	struct udevice *dev;
99 	struct regmap *map;
100 	uint reg;
101 
102 	sandbox_set_enable_memio(true);
103 	ut_assertok(uclass_get_device(UCLASS_SYSCON, 0, &dev));
104 	map = syscon_get_regmap(dev);
105 	ut_assertok_ptr(map);
106 
107 	ut_assertok(regmap_write(map, 0, 0xcacafafa));
108 	ut_assertok(regmap_write(map, 5, 0x55aa2211));
109 
110 	ut_assertok(regmap_read(map, 0, &reg));
111 	ut_asserteq(0xcacafafa, reg);
112 	ut_assertok(regmap_read(map, 5, &reg));
113 	ut_asserteq(0x55aa2211, reg);
114 
115 	ut_assertok(regmap_read(map, 0, &reg));
116 	ut_asserteq(0xcacafafa, reg);
117 	ut_assertok(regmap_update_bits(map, 0, 0xff00ff00, 0x55aa2211));
118 	ut_assertok(regmap_read(map, 0, &reg));
119 	ut_asserteq(0x55ca22fa, reg);
120 	ut_assertok(regmap_update_bits(map, 5, 0x00ff00ff, 0xcacafada));
121 	ut_assertok(regmap_read(map, 5, &reg));
122 	ut_asserteq(0x55ca22da, reg);
123 
124 	return 0;
125 }
126 
127 DM_TEST(dm_test_regmap_rw, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
128 
129 /* Get/Set test */
dm_test_regmap_getset(struct unit_test_state * uts)130 static int dm_test_regmap_getset(struct unit_test_state *uts)
131 {
132 	struct udevice *dev;
133 	struct regmap *map;
134 	uint reg;
135 	struct layout {
136 		u32 val0;
137 		u32 val1;
138 		u32 val2;
139 		u32 val3;
140 	};
141 
142 	sandbox_set_enable_memio(true);
143 	ut_assertok(uclass_get_device(UCLASS_SYSCON, 0, &dev));
144 	map = syscon_get_regmap(dev);
145 	ut_assertok_ptr(map);
146 
147 	regmap_set(map, struct layout, val0, 0xcacafafa);
148 	regmap_set(map, struct layout, val3, 0x55aa2211);
149 
150 	ut_assertok(regmap_get(map, struct layout, val0, &reg));
151 	ut_asserteq(0xcacafafa, reg);
152 	ut_assertok(regmap_get(map, struct layout, val3, &reg));
153 	ut_asserteq(0x55aa2211, reg);
154 
155 	return 0;
156 }
157 
158 DM_TEST(dm_test_regmap_getset, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
159 
160 /* Read polling test */
dm_test_regmap_poll(struct unit_test_state * uts)161 static int dm_test_regmap_poll(struct unit_test_state *uts)
162 {
163 	struct udevice *dev;
164 	struct regmap *map;
165 	uint reg;
166 	unsigned long start;
167 
168 	ut_assertok(uclass_get_device(UCLASS_SYSCON, 0, &dev));
169 	map = syscon_get_regmap(dev);
170 	ut_assertok_ptr(map);
171 
172 	start = get_timer(0);
173 
174 	ut_assertok(regmap_write(map, 0, 0x0));
175 	ut_asserteq(-ETIMEDOUT,
176 		    regmap_read_poll_timeout_test(map, 0, reg,
177 						  (reg == 0xcacafafa),
178 						  1, 5 * CONFIG_SYS_HZ,
179 						  5 * CONFIG_SYS_HZ));
180 
181 	ut_assert(get_timer(start) > (5 * CONFIG_SYS_HZ));
182 
183 	return 0;
184 }
185 
186 DM_TEST(dm_test_regmap_poll, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
187