xref: /openbmc/u-boot/test/dm/regmap.c (revision 35f9d9bd)
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 */
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 */
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 */
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 	ut_assertok(uclass_get_device(UCLASS_SYSCON, 0, &dev));
103 	map = syscon_get_regmap(dev);
104 	ut_assertok_ptr(map);
105 
106 	ut_assertok(regmap_write(map, 0, 0xcacafafa));
107 	ut_assertok(regmap_write(map, 3, 0x55aa2211));
108 
109 	ut_assertok(regmap_read(map, 0, &reg));
110 	ut_assertok(regmap_read(map, 3, &reg));
111 
112 	ut_assertok(regmap_update_bits(map, 0, 0xff00ff00, 0x55aa2211));
113 	ut_assertok(regmap_update_bits(map, 3, 0x00ff00ff, 0xcacafada));
114 
115 	return 0;
116 }
117 
118 DM_TEST(dm_test_regmap_rw, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
119 
120 /* Get/Set test */
121 static int dm_test_regmap_getset(struct unit_test_state *uts)
122 {
123 	struct udevice *dev;
124 	struct regmap *map;
125 	uint reg;
126 	struct layout {
127 		u32 val0;
128 		u32 val1;
129 		u32 val2;
130 		u32 val3;
131 	};
132 
133 	ut_assertok(uclass_get_device(UCLASS_SYSCON, 0, &dev));
134 	map = syscon_get_regmap(dev);
135 	ut_assertok_ptr(map);
136 
137 	regmap_set(map, struct layout, val0, 0xcacafafa);
138 	regmap_set(map, struct layout, val3, 0x55aa2211);
139 
140 	ut_assertok(regmap_get(map, struct layout, val0, &reg));
141 	ut_assertok(regmap_get(map, struct layout, val3, &reg));
142 
143 	return 0;
144 }
145 
146 DM_TEST(dm_test_regmap_getset, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
147 
148 /* Read polling test */
149 static int dm_test_regmap_poll(struct unit_test_state *uts)
150 {
151 	struct udevice *dev;
152 	struct regmap *map;
153 	uint reg;
154 	unsigned long start;
155 
156 	ut_assertok(uclass_get_device(UCLASS_SYSCON, 0, &dev));
157 	map = syscon_get_regmap(dev);
158 	ut_assertok_ptr(map);
159 
160 	start = get_timer(0);
161 
162 	ut_asserteq(-ETIMEDOUT,
163 		    regmap_read_poll_timeout(map, 0, reg,
164 					     (reg == 0xcacafafa),
165 					     1, 5 * CONFIG_SYS_HZ));
166 
167 	ut_assert(get_timer(start) > (5 * CONFIG_SYS_HZ));
168 
169 	return 0;
170 }
171 
172 DM_TEST(dm_test_regmap_poll, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
173