xref: /openbmc/u-boot/drivers/axi/sandbox_store.c (revision b71d9e8b)
1*9a8bcabdSMario Six // SPDX-License-Identifier: GPL-2.0+
2*9a8bcabdSMario Six /*
3*9a8bcabdSMario Six  * (C) Copyright 2018
4*9a8bcabdSMario Six  * Mario Six, Guntermann & Drunck GmbH, mario.six@gdsys.cc
5*9a8bcabdSMario Six  */
6*9a8bcabdSMario Six 
7*9a8bcabdSMario Six #include <common.h>
8*9a8bcabdSMario Six #include <axi.h>
9*9a8bcabdSMario Six #include <dm.h>
10*9a8bcabdSMario Six 
11*9a8bcabdSMario Six /**
12*9a8bcabdSMario Six  * struct sandbox_store_priv - Private data structure of a AXI store device
13*9a8bcabdSMario Six  * @store: The buffer holding the device's internal memory, which is read from
14*9a8bcabdSMario Six  *	   and written to using the driver's methods
15*9a8bcabdSMario Six  */
16*9a8bcabdSMario Six struct sandbox_store_priv {
17*9a8bcabdSMario Six 	u8 *store;
18*9a8bcabdSMario Six };
19*9a8bcabdSMario Six 
20*9a8bcabdSMario Six /**
21*9a8bcabdSMario Six  * copy_axi_data() - Copy data from source to destination with a given AXI
22*9a8bcabdSMario Six  *		     transfer width
23*9a8bcabdSMario Six  * @src:  Pointer to the data source from where data will be read
24*9a8bcabdSMario Six  * @dst:  Pointer to the data destination where data will be written to
25*9a8bcabdSMario Six  * @size: Size of the data to be copied given by a axi_size_t enum value
26*9a8bcabdSMario Six  *
27*9a8bcabdSMario Six  * Return: 0 if OK, -ve on error
28*9a8bcabdSMario Six  */
copy_axi_data(void * src,void * dst,enum axi_size_t size)29*9a8bcabdSMario Six static int copy_axi_data(void *src, void *dst, enum axi_size_t size)
30*9a8bcabdSMario Six {
31*9a8bcabdSMario Six 	switch (size) {
32*9a8bcabdSMario Six 	case AXI_SIZE_8:
33*9a8bcabdSMario Six 		*((u8 *)dst) = *((u8 *)src);
34*9a8bcabdSMario Six 		return 0;
35*9a8bcabdSMario Six 	case AXI_SIZE_16:
36*9a8bcabdSMario Six 		*((u16 *)dst) = be16_to_cpu(*((u16 *)src));
37*9a8bcabdSMario Six 		return 0;
38*9a8bcabdSMario Six 	case AXI_SIZE_32:
39*9a8bcabdSMario Six 		*((u32 *)dst) = be32_to_cpu(*((u32 *)src));
40*9a8bcabdSMario Six 		return 0;
41*9a8bcabdSMario Six 	default:
42*9a8bcabdSMario Six 		debug("%s: Unknown AXI transfer size '%d'\n", __func__, size);
43*9a8bcabdSMario Six 		return -EINVAL;
44*9a8bcabdSMario Six 	}
45*9a8bcabdSMario Six }
46*9a8bcabdSMario Six 
sandbox_store_read(struct udevice * dev,ulong address,void * data,enum axi_size_t size)47*9a8bcabdSMario Six static int sandbox_store_read(struct udevice *dev, ulong address, void *data,
48*9a8bcabdSMario Six 			      enum axi_size_t size)
49*9a8bcabdSMario Six {
50*9a8bcabdSMario Six 	struct sandbox_store_priv *priv = dev_get_priv(dev);
51*9a8bcabdSMario Six 
52*9a8bcabdSMario Six 	return copy_axi_data(priv->store + address, data, size);
53*9a8bcabdSMario Six }
54*9a8bcabdSMario Six 
sandbox_store_write(struct udevice * dev,ulong address,void * data,enum axi_size_t size)55*9a8bcabdSMario Six static int sandbox_store_write(struct udevice *dev, ulong address, void *data,
56*9a8bcabdSMario Six 			       enum axi_size_t size)
57*9a8bcabdSMario Six {
58*9a8bcabdSMario Six 	struct sandbox_store_priv *priv = dev_get_priv(dev);
59*9a8bcabdSMario Six 
60*9a8bcabdSMario Six 	return copy_axi_data(data, priv->store + address, size);
61*9a8bcabdSMario Six }
62*9a8bcabdSMario Six 
sandbox_store_get_store(struct udevice * dev,u8 ** store)63*9a8bcabdSMario Six static int sandbox_store_get_store(struct udevice *dev, u8 **store)
64*9a8bcabdSMario Six {
65*9a8bcabdSMario Six 	struct sandbox_store_priv *priv = dev_get_priv(dev);
66*9a8bcabdSMario Six 
67*9a8bcabdSMario Six 	*store = priv->store;
68*9a8bcabdSMario Six 
69*9a8bcabdSMario Six 	return 0;
70*9a8bcabdSMario Six }
71*9a8bcabdSMario Six 
72*9a8bcabdSMario Six static const struct udevice_id sandbox_store_ids[] = {
73*9a8bcabdSMario Six 	{ .compatible = "sandbox,sandbox_store" },
74*9a8bcabdSMario Six 	{ /* sentinel */ }
75*9a8bcabdSMario Six };
76*9a8bcabdSMario Six 
77*9a8bcabdSMario Six static const struct axi_emul_ops sandbox_store_ops = {
78*9a8bcabdSMario Six 	.read = sandbox_store_read,
79*9a8bcabdSMario Six 	.write = sandbox_store_write,
80*9a8bcabdSMario Six 	.get_store = sandbox_store_get_store,
81*9a8bcabdSMario Six };
82*9a8bcabdSMario Six 
sandbox_store_probe(struct udevice * dev)83*9a8bcabdSMario Six static int sandbox_store_probe(struct udevice *dev)
84*9a8bcabdSMario Six {
85*9a8bcabdSMario Six 	struct sandbox_store_priv *priv = dev_get_priv(dev);
86*9a8bcabdSMario Six 	u32 reg[2];
87*9a8bcabdSMario Six 	int ret;
88*9a8bcabdSMario Six 
89*9a8bcabdSMario Six 	ret = dev_read_u32_array(dev, "reg", reg, ARRAY_SIZE(reg));
90*9a8bcabdSMario Six 	if (ret) {
91*9a8bcabdSMario Six 		debug("%s: Could not read 'reg' property\n", dev->name);
92*9a8bcabdSMario Six 		return -EINVAL;
93*9a8bcabdSMario Six 	}
94*9a8bcabdSMario Six 
95*9a8bcabdSMario Six 	/*
96*9a8bcabdSMario Six 	 * Allocate the device's internal storage that will be read
97*9a8bcabdSMario Six 	 * from/written to
98*9a8bcabdSMario Six 	 */
99*9a8bcabdSMario Six 	priv->store = calloc(reg[1], 1);
100*9a8bcabdSMario Six 	if (!priv->store)
101*9a8bcabdSMario Six 		return -ENOMEM;
102*9a8bcabdSMario Six 
103*9a8bcabdSMario Six 	return 0;
104*9a8bcabdSMario Six }
105*9a8bcabdSMario Six 
sandbox_store_remove(struct udevice * dev)106*9a8bcabdSMario Six static int sandbox_store_remove(struct udevice *dev)
107*9a8bcabdSMario Six {
108*9a8bcabdSMario Six 	struct sandbox_store_priv *priv = dev_get_priv(dev);
109*9a8bcabdSMario Six 
110*9a8bcabdSMario Six 	free(priv->store);
111*9a8bcabdSMario Six 
112*9a8bcabdSMario Six 	return 0;
113*9a8bcabdSMario Six }
114*9a8bcabdSMario Six 
115*9a8bcabdSMario Six U_BOOT_DRIVER(sandbox_axi_store) = {
116*9a8bcabdSMario Six 	.name           = "sandbox_axi_store",
117*9a8bcabdSMario Six 	.id             = UCLASS_AXI_EMUL,
118*9a8bcabdSMario Six 	.of_match       = sandbox_store_ids,
119*9a8bcabdSMario Six 	.ops		= &sandbox_store_ops,
120*9a8bcabdSMario Six 	.priv_auto_alloc_size = sizeof(struct sandbox_store_priv),
121*9a8bcabdSMario Six 	.probe          = sandbox_store_probe,
122*9a8bcabdSMario Six 	.remove		= sandbox_store_remove,
123*9a8bcabdSMario Six };
124