One of important features of regmap [at least in Linux kernel] is an ability to seamlessly communicate to devices connected via different buses like: MMIO, SPI, I2C and many others.
Current implementation in U-Boot only supports memory-mapped registers which is a vere valid case but we'll need more in the future. This change paves the way for support of other buses. Still all existing users of regmap in U-Boot shouldn't be affected because for now we don't change API which might be required once we start adding support of more complicated cases like 8/16/32/64-bit accessors, big- and little-endian flavours etc. It was inspired by discussion [1] of addition of even more accessors to a standard 16550 UART. [1] https://lists.denx.de/pipermail/u-boot/2018-March/322322.html Signed-off-by: Alexey Brodkin <[email protected]> Cc: Simon Glass <[email protected]> --- drivers/core/Makefile | 2 +- drivers/core/{regmap.c => regmap-mem.c} | 79 ++++++----------------- drivers/core/regmap.c | 85 +------------------------ include/regmap.h | 9 +++ 4 files changed, 31 insertions(+), 144 deletions(-) copy drivers/core/{regmap.c => regmap-mem.c} (60%) diff --git a/drivers/core/Makefile b/drivers/core/Makefile index a5039c5bd311..ce9b32600e97 100644 --- a/drivers/core/Makefile +++ b/drivers/core/Makefile @@ -9,7 +9,7 @@ obj-$(CONFIG_DEVRES) += devres.o obj-$(CONFIG_$(SPL_)DM_DEVICE_REMOVE) += device-remove.o obj-$(CONFIG_$(SPL_)SIMPLE_BUS) += simple-bus.o obj-$(CONFIG_DM) += dump.o -obj-$(CONFIG_$(SPL_TPL_)REGMAP) += regmap.o +obj-$(CONFIG_$(SPL_TPL_)REGMAP) += regmap.o regmap-mem.o obj-$(CONFIG_$(SPL_TPL_)SYSCON) += syscon-uclass.o obj-$(CONFIG_OF_LIVE) += of_access.o of_addr.o ifndef CONFIG_DM_DEV_READ_INLINE diff --git a/drivers/core/regmap.c b/drivers/core/regmap-mem.c similarity index 60% copy from drivers/core/regmap.c copy to drivers/core/regmap-mem.c index 8a0e00ff9aa6..e252794d553d 100644 --- a/drivers/core/regmap.c +++ b/drivers/core/regmap-mem.c @@ -1,42 +1,34 @@ /* - * Copyright (c) 2015 Google, Inc - * Written by Simon Glass <[email protected]> + * Copyright (c) 2018 Synopsys, Inc + * Written by Simon Glass <[email protected]> and + * Alexey Brodkin <[email protected]> * * SPDX-License-Identifier: GPL-2.0+ */ #include <common.h> #include <dm.h> -#include <errno.h> -#include <linux/libfdt.h> -#include <malloc.h> -#include <mapmem.h> #include <regmap.h> #include <asm/io.h> #include <dm/of_addr.h> #include <linux/ioport.h> -DECLARE_GLOBAL_DATA_PTR; +int regmap_mem_read(struct regmap *map, uint offset, uint *valp) +{ + u32 *ptr = map_physmem(map->base + offset, sizeof(u32), MAP_NOCACHE); + + *valp = le32_to_cpu(readl(ptr)); + + return 0; +} -static struct regmap *regmap_alloc_count(int count) +int regmap_mem_write(struct regmap *map, uint offset, uint val) { - struct regmap *map; + u32 *ptr = map_physmem(map->base + offset, sizeof(u32), MAP_NOCACHE); - map = malloc(sizeof(struct regmap)); - if (!map) - return NULL; - if (count <= 1) { - map->range = &map->base_range; - } else { - map->range = malloc(count * sizeof(struct regmap_range)); - if (!map->range) { - free(map); - return NULL; - } - } - map->range_count = count; + writel(cpu_to_le32(val), ptr); - return map; + return 0; } #if CONFIG_IS_ENABLED(OF_PLATDATA) @@ -91,6 +83,7 @@ int regmap_init_mem(struct udevice *dev, struct regmap **mapp) for (range = map->range, index = 0; count > 0; count--, range++, index++) { fdt_size_t sz; + if (of_live_active()) { of_address_to_resource(ofnode_to_np(node), index, &r); range->start = r.start; @@ -103,47 +96,11 @@ int regmap_init_mem(struct udevice *dev, struct regmap **mapp) } } map->base = map->range[0].start; + map->reg_read = regmap_mem_read; + map->reg_write = regmap_mem_write; *mapp = map; return 0; } #endif - -void *regmap_get_range(struct regmap *map, unsigned int range_num) -{ - struct regmap_range *range; - - if (range_num >= map->range_count) - return NULL; - range = &map->range[range_num]; - - return map_sysmem(range->start, range->size); -} - -int regmap_uninit(struct regmap *map) -{ - if (map->range_count > 1) - free(map->range); - free(map); - - return 0; -} - -int regmap_read(struct regmap *map, uint offset, uint *valp) -{ - uint32_t *ptr = map_physmem(map->base + offset, 4, MAP_NOCACHE); - - *valp = le32_to_cpu(readl(ptr)); - - return 0; -} - -int regmap_write(struct regmap *map, uint offset, uint val) -{ - uint32_t *ptr = map_physmem(map->base + offset, 4, MAP_NOCACHE); - - writel(cpu_to_le32(val), ptr); - - return 0; -} diff --git a/drivers/core/regmap.c b/drivers/core/regmap.c index 8a0e00ff9aa6..0d6558676636 100644 --- a/drivers/core/regmap.c +++ b/drivers/core/regmap.c @@ -18,7 +18,7 @@ DECLARE_GLOBAL_DATA_PTR; -static struct regmap *regmap_alloc_count(int count) +struct regmap *regmap_alloc_count(int count) { struct regmap *map; @@ -39,77 +39,6 @@ static struct regmap *regmap_alloc_count(int count) return map; } -#if CONFIG_IS_ENABLED(OF_PLATDATA) -int regmap_init_mem_platdata(struct udevice *dev, fdt_val_t *reg, int count, - struct regmap **mapp) -{ - struct regmap_range *range; - struct regmap *map; - - map = regmap_alloc_count(count); - if (!map) - return -ENOMEM; - - map->base = *reg; - for (range = map->range; count > 0; reg += 2, range++, count--) { - range->start = *reg; - range->size = reg[1]; - } - - *mapp = map; - - return 0; -} -#else -int regmap_init_mem(struct udevice *dev, struct regmap **mapp) -{ - struct regmap_range *range; - struct regmap *map; - int count; - int addr_len, size_len, both_len; - int len; - int index; - ofnode node = dev_ofnode(dev); - struct resource r; - - addr_len = dev_read_simple_addr_cells(dev->parent); - size_len = dev_read_simple_size_cells(dev->parent); - both_len = addr_len + size_len; - - len = dev_read_size(dev, "reg"); - if (len < 0) - return len; - len /= sizeof(fdt32_t); - count = len / both_len; - if (!count) - return -EINVAL; - - map = regmap_alloc_count(count); - if (!map) - return -ENOMEM; - - for (range = map->range, index = 0; count > 0; - count--, range++, index++) { - fdt_size_t sz; - if (of_live_active()) { - of_address_to_resource(ofnode_to_np(node), index, &r); - range->start = r.start; - range->size = r.end - r.start + 1; - } else { - range->start = fdtdec_get_addr_size_fixed(gd->fdt_blob, - dev_of_offset(dev), "reg", index, - addr_len, size_len, &sz, true); - range->size = sz; - } - } - map->base = map->range[0].start; - - *mapp = map; - - return 0; -} -#endif - void *regmap_get_range(struct regmap *map, unsigned int range_num) { struct regmap_range *range; @@ -132,18 +61,10 @@ int regmap_uninit(struct regmap *map) int regmap_read(struct regmap *map, uint offset, uint *valp) { - uint32_t *ptr = map_physmem(map->base + offset, 4, MAP_NOCACHE); - - *valp = le32_to_cpu(readl(ptr)); - - return 0; + return map->reg_read(map, offset, valp); } int regmap_write(struct regmap *map, uint offset, uint val) { - uint32_t *ptr = map_physmem(map->base + offset, 4, MAP_NOCACHE); - - writel(cpu_to_le32(val), ptr); - - return 0; + return map->reg_write(map, offset, val); } diff --git a/include/regmap.h b/include/regmap.h index 493a5d8eff84..f01c5733afac 100644 --- a/include/regmap.h +++ b/include/regmap.h @@ -31,6 +31,8 @@ struct regmap { phys_addr_t base; int range_count; struct regmap_range *range, base_range; + int (*reg_read)(struct regmap *map, uint reg, uint *val); + int (*reg_write)(struct regmap *map, uint reg, uint val); }; /* @@ -80,6 +82,13 @@ int regmap_init_mem_platdata(struct udevice *dev, fdt_val_t *reg, int count, */ void *regmap_get_range(struct regmap *map, unsigned int range_num); +/** + * regmap_alloc_count() - Allocate specified amount of regmap ranges + * + * @count: Amount of regmap ranges to allocate + */ +struct regmap *regmap_alloc_count(int count); + /** * regmap_uninit() - free a previously inited regmap */ -- 2.17.0 _______________________________________________ U-Boot mailing list [email protected] https://lists.denx.de/listinfo/u-boot

