regmap.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright (c) 2015 Google, Inc
  4. * Written by Simon Glass <sjg@chromium.org>
  5. */
  6. #include <common.h>
  7. #include <dm.h>
  8. #include <errno.h>
  9. #include <log.h>
  10. #include <linux/libfdt.h>
  11. #include <malloc.h>
  12. #include <mapmem.h>
  13. #include <regmap.h>
  14. #include <asm/io.h>
  15. #include <dm/of_addr.h>
  16. #include <dm/devres.h>
  17. #include <linux/ioport.h>
  18. #include <linux/compat.h>
  19. #include <linux/err.h>
  20. #include <linux/bitops.h>
  21. /*
  22. * Internal representation of a regmap field. Instead of storing the MSB and
  23. * LSB, store the shift and mask. This makes the code a bit cleaner and faster
  24. * because the shift and mask don't have to be calculated every time.
  25. */
  26. struct regmap_field {
  27. struct regmap *regmap;
  28. unsigned int mask;
  29. /* lsb */
  30. unsigned int shift;
  31. unsigned int reg;
  32. };
  33. DECLARE_GLOBAL_DATA_PTR;
  34. /**
  35. * regmap_alloc() - Allocate a regmap with a given number of ranges.
  36. *
  37. * @count: Number of ranges to be allocated for the regmap.
  38. *
  39. * The default regmap width is set to REGMAP_SIZE_32. Callers can override it
  40. * if they need.
  41. *
  42. * Return: A pointer to the newly allocated regmap, or NULL on error.
  43. */
  44. static struct regmap *regmap_alloc(int count)
  45. {
  46. struct regmap *map;
  47. size_t size = sizeof(*map) + sizeof(map->ranges[0]) * count;
  48. map = calloc(1, size);
  49. if (!map)
  50. return NULL;
  51. map->range_count = count;
  52. map->width = REGMAP_SIZE_32;
  53. return map;
  54. }
  55. #if CONFIG_IS_ENABLED(OF_PLATDATA)
  56. int regmap_init_mem_platdata(struct udevice *dev, fdt_val_t *reg, int count,
  57. struct regmap **mapp)
  58. {
  59. struct regmap_range *range;
  60. struct regmap *map;
  61. map = regmap_alloc(count);
  62. if (!map)
  63. return -ENOMEM;
  64. for (range = map->ranges; count > 0; reg += 2, range++, count--) {
  65. range->start = *reg;
  66. range->size = reg[1];
  67. }
  68. *mapp = map;
  69. return 0;
  70. }
  71. #else
  72. /**
  73. * init_range() - Initialize a single range of a regmap
  74. * @node: Device node that will use the map in question
  75. * @range: Pointer to a regmap_range structure that will be initialized
  76. * @addr_len: The length of the addr parts of the reg property
  77. * @size_len: The length of the size parts of the reg property
  78. * @index: The index of the range to initialize
  79. *
  80. * This function will read the necessary 'reg' information from the device tree
  81. * (the 'addr' part, and the 'length' part), and initialize the range in
  82. * quesion.
  83. *
  84. * Return: 0 if OK, -ve on error
  85. */
  86. static int init_range(ofnode node, struct regmap_range *range, int addr_len,
  87. int size_len, int index)
  88. {
  89. fdt_size_t sz;
  90. struct resource r;
  91. if (of_live_active()) {
  92. int ret;
  93. ret = of_address_to_resource(ofnode_to_np(node),
  94. index, &r);
  95. if (ret) {
  96. debug("%s: Could not read resource of range %d (ret = %d)\n",
  97. ofnode_get_name(node), index, ret);
  98. return ret;
  99. }
  100. range->start = r.start;
  101. range->size = r.end - r.start + 1;
  102. } else {
  103. int offset = ofnode_to_offset(node);
  104. range->start = fdtdec_get_addr_size_fixed(gd->fdt_blob, offset,
  105. "reg", index,
  106. addr_len, size_len,
  107. &sz, true);
  108. if (range->start == FDT_ADDR_T_NONE) {
  109. debug("%s: Could not read start of range %d\n",
  110. ofnode_get_name(node), index);
  111. return -EINVAL;
  112. }
  113. range->size = sz;
  114. }
  115. return 0;
  116. }
  117. int regmap_init_mem_index(ofnode node, struct regmap **mapp, int index)
  118. {
  119. struct regmap *map;
  120. int addr_len, size_len;
  121. int ret;
  122. addr_len = ofnode_read_simple_addr_cells(ofnode_get_parent(node));
  123. if (addr_len < 0) {
  124. debug("%s: Error while reading the addr length (ret = %d)\n",
  125. ofnode_get_name(node), addr_len);
  126. return addr_len;
  127. }
  128. size_len = ofnode_read_simple_size_cells(ofnode_get_parent(node));
  129. if (size_len < 0) {
  130. debug("%s: Error while reading the size length: (ret = %d)\n",
  131. ofnode_get_name(node), size_len);
  132. return size_len;
  133. }
  134. map = regmap_alloc(1);
  135. if (!map)
  136. return -ENOMEM;
  137. ret = init_range(node, map->ranges, addr_len, size_len, index);
  138. if (ret)
  139. goto err;
  140. if (ofnode_read_bool(node, "little-endian"))
  141. map->endianness = REGMAP_LITTLE_ENDIAN;
  142. else if (ofnode_read_bool(node, "big-endian"))
  143. map->endianness = REGMAP_BIG_ENDIAN;
  144. else if (ofnode_read_bool(node, "native-endian"))
  145. map->endianness = REGMAP_NATIVE_ENDIAN;
  146. else /* Default: native endianness */
  147. map->endianness = REGMAP_NATIVE_ENDIAN;
  148. *mapp = map;
  149. return 0;
  150. err:
  151. regmap_uninit(map);
  152. return ret;
  153. }
  154. int regmap_init_mem_range(ofnode node, ulong r_start, ulong r_size,
  155. struct regmap **mapp)
  156. {
  157. struct regmap *map;
  158. struct regmap_range *range;
  159. map = regmap_alloc(1);
  160. if (!map)
  161. return -ENOMEM;
  162. range = &map->ranges[0];
  163. range->start = r_start;
  164. range->size = r_size;
  165. if (ofnode_read_bool(node, "little-endian"))
  166. map->endianness = REGMAP_LITTLE_ENDIAN;
  167. else if (ofnode_read_bool(node, "big-endian"))
  168. map->endianness = REGMAP_BIG_ENDIAN;
  169. else if (ofnode_read_bool(node, "native-endian"))
  170. map->endianness = REGMAP_NATIVE_ENDIAN;
  171. else /* Default: native endianness */
  172. map->endianness = REGMAP_NATIVE_ENDIAN;
  173. *mapp = map;
  174. return 0;
  175. }
  176. int regmap_init_mem(ofnode node, struct regmap **mapp)
  177. {
  178. struct regmap_range *range;
  179. struct regmap *map;
  180. int count;
  181. int addr_len, size_len, both_len;
  182. int len;
  183. int index;
  184. int ret;
  185. addr_len = ofnode_read_simple_addr_cells(ofnode_get_parent(node));
  186. if (addr_len < 0) {
  187. debug("%s: Error while reading the addr length (ret = %d)\n",
  188. ofnode_get_name(node), addr_len);
  189. return addr_len;
  190. }
  191. size_len = ofnode_read_simple_size_cells(ofnode_get_parent(node));
  192. if (size_len < 0) {
  193. debug("%s: Error while reading the size length: (ret = %d)\n",
  194. ofnode_get_name(node), size_len);
  195. return size_len;
  196. }
  197. both_len = addr_len + size_len;
  198. if (!both_len) {
  199. debug("%s: Both addr and size length are zero\n",
  200. ofnode_get_name(node));
  201. return -EINVAL;
  202. }
  203. len = ofnode_read_size(node, "reg");
  204. if (len < 0) {
  205. debug("%s: Error while reading reg size (ret = %d)\n",
  206. ofnode_get_name(node), len);
  207. return len;
  208. }
  209. len /= sizeof(fdt32_t);
  210. count = len / both_len;
  211. if (!count) {
  212. debug("%s: Not enough data in reg property\n",
  213. ofnode_get_name(node));
  214. return -EINVAL;
  215. }
  216. map = regmap_alloc(count);
  217. if (!map)
  218. return -ENOMEM;
  219. for (range = map->ranges, index = 0; count > 0;
  220. count--, range++, index++) {
  221. ret = init_range(node, range, addr_len, size_len, index);
  222. if (ret)
  223. goto err;
  224. }
  225. if (ofnode_read_bool(node, "little-endian"))
  226. map->endianness = REGMAP_LITTLE_ENDIAN;
  227. else if (ofnode_read_bool(node, "big-endian"))
  228. map->endianness = REGMAP_BIG_ENDIAN;
  229. else if (ofnode_read_bool(node, "native-endian"))
  230. map->endianness = REGMAP_NATIVE_ENDIAN;
  231. else /* Default: native endianness */
  232. map->endianness = REGMAP_NATIVE_ENDIAN;
  233. *mapp = map;
  234. return 0;
  235. err:
  236. regmap_uninit(map);
  237. return ret;
  238. }
  239. static void devm_regmap_release(struct udevice *dev, void *res)
  240. {
  241. regmap_uninit(*(struct regmap **)res);
  242. }
  243. struct regmap *devm_regmap_init(struct udevice *dev,
  244. const struct regmap_bus *bus,
  245. void *bus_context,
  246. const struct regmap_config *config)
  247. {
  248. int rc;
  249. struct regmap **mapp, *map;
  250. mapp = devres_alloc(devm_regmap_release, sizeof(struct regmap *),
  251. __GFP_ZERO);
  252. if (unlikely(!mapp))
  253. return ERR_PTR(-ENOMEM);
  254. if (config && config->r_size != 0)
  255. rc = regmap_init_mem_range(dev_ofnode(dev), config->r_start,
  256. config->r_size, mapp);
  257. else
  258. rc = regmap_init_mem(dev_ofnode(dev), mapp);
  259. if (rc)
  260. return ERR_PTR(rc);
  261. map = *mapp;
  262. if (config) {
  263. map->width = config->width;
  264. map->reg_offset_shift = config->reg_offset_shift;
  265. }
  266. devres_add(dev, mapp);
  267. return *mapp;
  268. }
  269. #endif
  270. void *regmap_get_range(struct regmap *map, unsigned int range_num)
  271. {
  272. struct regmap_range *range;
  273. if (range_num >= map->range_count)
  274. return NULL;
  275. range = &map->ranges[range_num];
  276. return map_sysmem(range->start, range->size);
  277. }
  278. int regmap_uninit(struct regmap *map)
  279. {
  280. free(map);
  281. return 0;
  282. }
  283. static inline u8 __read_8(u8 *addr, enum regmap_endianness_t endianness)
  284. {
  285. return readb(addr);
  286. }
  287. static inline u16 __read_16(u16 *addr, enum regmap_endianness_t endianness)
  288. {
  289. switch (endianness) {
  290. case REGMAP_LITTLE_ENDIAN:
  291. return in_le16(addr);
  292. case REGMAP_BIG_ENDIAN:
  293. return in_be16(addr);
  294. case REGMAP_NATIVE_ENDIAN:
  295. return readw(addr);
  296. }
  297. return readw(addr);
  298. }
  299. static inline u32 __read_32(u32 *addr, enum regmap_endianness_t endianness)
  300. {
  301. switch (endianness) {
  302. case REGMAP_LITTLE_ENDIAN:
  303. return in_le32(addr);
  304. case REGMAP_BIG_ENDIAN:
  305. return in_be32(addr);
  306. case REGMAP_NATIVE_ENDIAN:
  307. return readl(addr);
  308. }
  309. return readl(addr);
  310. }
  311. #if defined(in_le64) && defined(in_be64) && defined(readq)
  312. static inline u64 __read_64(u64 *addr, enum regmap_endianness_t endianness)
  313. {
  314. switch (endianness) {
  315. case REGMAP_LITTLE_ENDIAN:
  316. return in_le64(addr);
  317. case REGMAP_BIG_ENDIAN:
  318. return in_be64(addr);
  319. case REGMAP_NATIVE_ENDIAN:
  320. return readq(addr);
  321. }
  322. return readq(addr);
  323. }
  324. #endif
  325. int regmap_raw_read_range(struct regmap *map, uint range_num, uint offset,
  326. void *valp, size_t val_len)
  327. {
  328. struct regmap_range *range;
  329. void *ptr;
  330. if (range_num >= map->range_count) {
  331. debug("%s: range index %d larger than range count\n",
  332. __func__, range_num);
  333. return -ERANGE;
  334. }
  335. range = &map->ranges[range_num];
  336. offset <<= map->reg_offset_shift;
  337. if (offset + val_len > range->size) {
  338. debug("%s: offset/size combination invalid\n", __func__);
  339. return -ERANGE;
  340. }
  341. ptr = map_physmem(range->start + offset, val_len, MAP_NOCACHE);
  342. switch (val_len) {
  343. case REGMAP_SIZE_8:
  344. *((u8 *)valp) = __read_8(ptr, map->endianness);
  345. break;
  346. case REGMAP_SIZE_16:
  347. *((u16 *)valp) = __read_16(ptr, map->endianness);
  348. break;
  349. case REGMAP_SIZE_32:
  350. *((u32 *)valp) = __read_32(ptr, map->endianness);
  351. break;
  352. #if defined(in_le64) && defined(in_be64) && defined(readq)
  353. case REGMAP_SIZE_64:
  354. *((u64 *)valp) = __read_64(ptr, map->endianness);
  355. break;
  356. #endif
  357. default:
  358. debug("%s: regmap size %zu unknown\n", __func__, val_len);
  359. return -EINVAL;
  360. }
  361. return 0;
  362. }
  363. int regmap_raw_read(struct regmap *map, uint offset, void *valp, size_t val_len)
  364. {
  365. return regmap_raw_read_range(map, 0, offset, valp, val_len);
  366. }
  367. int regmap_read(struct regmap *map, uint offset, uint *valp)
  368. {
  369. return regmap_raw_read(map, offset, valp, map->width);
  370. }
  371. static inline void __write_8(u8 *addr, const u8 *val,
  372. enum regmap_endianness_t endianness)
  373. {
  374. writeb(*val, addr);
  375. }
  376. static inline void __write_16(u16 *addr, const u16 *val,
  377. enum regmap_endianness_t endianness)
  378. {
  379. switch (endianness) {
  380. case REGMAP_NATIVE_ENDIAN:
  381. writew(*val, addr);
  382. break;
  383. case REGMAP_LITTLE_ENDIAN:
  384. out_le16(addr, *val);
  385. break;
  386. case REGMAP_BIG_ENDIAN:
  387. out_be16(addr, *val);
  388. break;
  389. }
  390. }
  391. static inline void __write_32(u32 *addr, const u32 *val,
  392. enum regmap_endianness_t endianness)
  393. {
  394. switch (endianness) {
  395. case REGMAP_NATIVE_ENDIAN:
  396. writel(*val, addr);
  397. break;
  398. case REGMAP_LITTLE_ENDIAN:
  399. out_le32(addr, *val);
  400. break;
  401. case REGMAP_BIG_ENDIAN:
  402. out_be32(addr, *val);
  403. break;
  404. }
  405. }
  406. #if defined(out_le64) && defined(out_be64) && defined(writeq)
  407. static inline void __write_64(u64 *addr, const u64 *val,
  408. enum regmap_endianness_t endianness)
  409. {
  410. switch (endianness) {
  411. case REGMAP_NATIVE_ENDIAN:
  412. writeq(*val, addr);
  413. break;
  414. case REGMAP_LITTLE_ENDIAN:
  415. out_le64(addr, *val);
  416. break;
  417. case REGMAP_BIG_ENDIAN:
  418. out_be64(addr, *val);
  419. break;
  420. }
  421. }
  422. #endif
  423. int regmap_raw_write_range(struct regmap *map, uint range_num, uint offset,
  424. const void *val, size_t val_len)
  425. {
  426. struct regmap_range *range;
  427. void *ptr;
  428. if (range_num >= map->range_count) {
  429. debug("%s: range index %d larger than range count\n",
  430. __func__, range_num);
  431. return -ERANGE;
  432. }
  433. range = &map->ranges[range_num];
  434. offset <<= map->reg_offset_shift;
  435. if (offset + val_len > range->size) {
  436. debug("%s: offset/size combination invalid\n", __func__);
  437. return -ERANGE;
  438. }
  439. ptr = map_physmem(range->start + offset, val_len, MAP_NOCACHE);
  440. switch (val_len) {
  441. case REGMAP_SIZE_8:
  442. __write_8(ptr, val, map->endianness);
  443. break;
  444. case REGMAP_SIZE_16:
  445. __write_16(ptr, val, map->endianness);
  446. break;
  447. case REGMAP_SIZE_32:
  448. __write_32(ptr, val, map->endianness);
  449. break;
  450. #if defined(out_le64) && defined(out_be64) && defined(writeq)
  451. case REGMAP_SIZE_64:
  452. __write_64(ptr, val, map->endianness);
  453. break;
  454. #endif
  455. default:
  456. debug("%s: regmap size %zu unknown\n", __func__, val_len);
  457. return -EINVAL;
  458. }
  459. return 0;
  460. }
  461. int regmap_raw_write(struct regmap *map, uint offset, const void *val,
  462. size_t val_len)
  463. {
  464. return regmap_raw_write_range(map, 0, offset, val, val_len);
  465. }
  466. int regmap_write(struct regmap *map, uint offset, uint val)
  467. {
  468. return regmap_raw_write(map, offset, &val, map->width);
  469. }
  470. int regmap_update_bits(struct regmap *map, uint offset, uint mask, uint val)
  471. {
  472. uint reg;
  473. int ret;
  474. ret = regmap_read(map, offset, &reg);
  475. if (ret)
  476. return ret;
  477. reg &= ~mask;
  478. return regmap_write(map, offset, reg | (val & mask));
  479. }
  480. int regmap_field_read(struct regmap_field *field, unsigned int *val)
  481. {
  482. int ret;
  483. unsigned int reg_val;
  484. ret = regmap_read(field->regmap, field->reg, &reg_val);
  485. if (ret != 0)
  486. return ret;
  487. reg_val &= field->mask;
  488. reg_val >>= field->shift;
  489. *val = reg_val;
  490. return ret;
  491. }
  492. int regmap_field_write(struct regmap_field *field, unsigned int val)
  493. {
  494. return regmap_update_bits(field->regmap, field->reg, field->mask,
  495. val << field->shift);
  496. }
  497. static void regmap_field_init(struct regmap_field *rm_field,
  498. struct regmap *regmap,
  499. struct reg_field reg_field)
  500. {
  501. rm_field->regmap = regmap;
  502. rm_field->reg = reg_field.reg;
  503. rm_field->shift = reg_field.lsb;
  504. rm_field->mask = GENMASK(reg_field.msb, reg_field.lsb);
  505. }
  506. struct regmap_field *devm_regmap_field_alloc(struct udevice *dev,
  507. struct regmap *regmap,
  508. struct reg_field reg_field)
  509. {
  510. struct regmap_field *rm_field = devm_kzalloc(dev, sizeof(*rm_field),
  511. GFP_KERNEL);
  512. if (!rm_field)
  513. return ERR_PTR(-ENOMEM);
  514. regmap_field_init(rm_field, regmap, reg_field);
  515. return rm_field;
  516. }
  517. void devm_regmap_field_free(struct udevice *dev, struct regmap_field *field)
  518. {
  519. devm_kfree(dev, field);
  520. }
  521. struct regmap_field *regmap_field_alloc(struct regmap *regmap,
  522. struct reg_field reg_field)
  523. {
  524. struct regmap_field *rm_field = kzalloc(sizeof(*rm_field), GFP_KERNEL);
  525. if (!rm_field)
  526. return ERR_PTR(-ENOMEM);
  527. regmap_field_init(rm_field, regmap, reg_field);
  528. return rm_field;
  529. }
  530. void regmap_field_free(struct regmap_field *field)
  531. {
  532. kfree(field);
  533. }