xref: /openbmc/linux/drivers/soc/sunxi/sunxi_sram.c (revision 460d9cb6)
14af34b57SMaxime Ripard /*
24af34b57SMaxime Ripard  * Allwinner SoCs SRAM Controller Driver
34af34b57SMaxime Ripard  *
44af34b57SMaxime Ripard  * Copyright (C) 2015 Maxime Ripard
54af34b57SMaxime Ripard  *
64af34b57SMaxime Ripard  * Author: Maxime Ripard <maxime.ripard@free-electrons.com>
74af34b57SMaxime Ripard  *
84af34b57SMaxime Ripard  * This file is licensed under the terms of the GNU General Public
94af34b57SMaxime Ripard  * License version 2.  This program is licensed "as is" without any
104af34b57SMaxime Ripard  * warranty of any kind, whether express or implied.
114af34b57SMaxime Ripard  */
124af34b57SMaxime Ripard 
134af34b57SMaxime Ripard #include <linux/debugfs.h>
144af34b57SMaxime Ripard #include <linux/io.h>
154af34b57SMaxime Ripard #include <linux/module.h>
164af34b57SMaxime Ripard #include <linux/of.h>
174af34b57SMaxime Ripard #include <linux/of_address.h>
184af34b57SMaxime Ripard #include <linux/of_device.h>
194af34b57SMaxime Ripard #include <linux/platform_device.h>
205828729bSIcenowy Zheng #include <linux/regmap.h>
214af34b57SMaxime Ripard 
224af34b57SMaxime Ripard #include <linux/soc/sunxi/sunxi_sram.h>
234af34b57SMaxime Ripard 
244af34b57SMaxime Ripard struct sunxi_sram_func {
254af34b57SMaxime Ripard 	char	*func;
264af34b57SMaxime Ripard 	u8	val;
278fed2ce9SIcenowy Zheng 	u32	reg_val;
284af34b57SMaxime Ripard };
294af34b57SMaxime Ripard 
304af34b57SMaxime Ripard struct sunxi_sram_data {
314af34b57SMaxime Ripard 	char			*name;
324af34b57SMaxime Ripard 	u8			reg;
334af34b57SMaxime Ripard 	u8			offset;
344af34b57SMaxime Ripard 	u8			width;
354af34b57SMaxime Ripard 	struct sunxi_sram_func	*func;
364af34b57SMaxime Ripard 	struct list_head	list;
374af34b57SMaxime Ripard };
384af34b57SMaxime Ripard 
394af34b57SMaxime Ripard struct sunxi_sram_desc {
404af34b57SMaxime Ripard 	struct sunxi_sram_data	data;
414af34b57SMaxime Ripard 	bool			claimed;
424af34b57SMaxime Ripard };
434af34b57SMaxime Ripard 
448fed2ce9SIcenowy Zheng #define SUNXI_SRAM_MAP(_reg_val, _val, _func)			\
454af34b57SMaxime Ripard 	{							\
464af34b57SMaxime Ripard 		.func = _func,					\
474af34b57SMaxime Ripard 		.val = _val,					\
488fed2ce9SIcenowy Zheng 		.reg_val = _reg_val,				\
494af34b57SMaxime Ripard 	}
504af34b57SMaxime Ripard 
514af34b57SMaxime Ripard #define SUNXI_SRAM_DATA(_name, _reg, _off, _width, ...)		\
524af34b57SMaxime Ripard 	{							\
534af34b57SMaxime Ripard 		.name = _name,					\
544af34b57SMaxime Ripard 		.reg = _reg,					\
554af34b57SMaxime Ripard 		.offset = _off,					\
564af34b57SMaxime Ripard 		.width = _width,				\
574af34b57SMaxime Ripard 		.func = (struct sunxi_sram_func[]){		\
584af34b57SMaxime Ripard 			__VA_ARGS__, { } },			\
594af34b57SMaxime Ripard 	}
604af34b57SMaxime Ripard 
614af34b57SMaxime Ripard static struct sunxi_sram_desc sun4i_a10_sram_a3_a4 = {
624af34b57SMaxime Ripard 	.data	= SUNXI_SRAM_DATA("A3-A4", 0x4, 0x4, 2,
638fed2ce9SIcenowy Zheng 				  SUNXI_SRAM_MAP(0, 0, "cpu"),
648fed2ce9SIcenowy Zheng 				  SUNXI_SRAM_MAP(1, 1, "emac")),
654af34b57SMaxime Ripard };
664af34b57SMaxime Ripard 
675fdec16bSMaxime Ripard static struct sunxi_sram_desc sun4i_a10_sram_c1 = {
685fdec16bSMaxime Ripard 	.data	= SUNXI_SRAM_DATA("C1", 0x0, 0x0, 31,
695fdec16bSMaxime Ripard 				  SUNXI_SRAM_MAP(0, 0, "cpu"),
705fdec16bSMaxime Ripard 				  SUNXI_SRAM_MAP(0x7fffffff, 1, "ve")),
715fdec16bSMaxime Ripard };
725fdec16bSMaxime Ripard 
734af34b57SMaxime Ripard static struct sunxi_sram_desc sun4i_a10_sram_d = {
744af34b57SMaxime Ripard 	.data	= SUNXI_SRAM_DATA("D", 0x4, 0x0, 1,
758fed2ce9SIcenowy Zheng 				  SUNXI_SRAM_MAP(0, 0, "cpu"),
768fed2ce9SIcenowy Zheng 				  SUNXI_SRAM_MAP(1, 1, "usb-otg")),
774af34b57SMaxime Ripard };
784af34b57SMaxime Ripard 
795e4fb642SIcenowy Zheng static struct sunxi_sram_desc sun50i_a64_sram_c = {
805e4fb642SIcenowy Zheng 	.data	= SUNXI_SRAM_DATA("C", 0x4, 24, 1,
81e3c95edbSSamuel Holland 				  SUNXI_SRAM_MAP(1, 0, "cpu"),
82e3c95edbSSamuel Holland 				  SUNXI_SRAM_MAP(0, 1, "de2")),
835e4fb642SIcenowy Zheng };
845e4fb642SIcenowy Zheng 
854af34b57SMaxime Ripard static const struct of_device_id sunxi_sram_dt_ids[] = {
864af34b57SMaxime Ripard 	{
874af34b57SMaxime Ripard 		.compatible	= "allwinner,sun4i-a10-sram-a3-a4",
884af34b57SMaxime Ripard 		.data		= &sun4i_a10_sram_a3_a4.data,
894af34b57SMaxime Ripard 	},
904af34b57SMaxime Ripard 	{
915fdec16bSMaxime Ripard 		.compatible	= "allwinner,sun4i-a10-sram-c1",
925fdec16bSMaxime Ripard 		.data		= &sun4i_a10_sram_c1.data,
935fdec16bSMaxime Ripard 	},
945fdec16bSMaxime Ripard 	{
954af34b57SMaxime Ripard 		.compatible	= "allwinner,sun4i-a10-sram-d",
964af34b57SMaxime Ripard 		.data		= &sun4i_a10_sram_d.data,
974af34b57SMaxime Ripard 	},
985e4fb642SIcenowy Zheng 	{
995e4fb642SIcenowy Zheng 		.compatible	= "allwinner,sun50i-a64-sram-c",
1005e4fb642SIcenowy Zheng 		.data		= &sun50i_a64_sram_c.data,
1015e4fb642SIcenowy Zheng 	},
1024af34b57SMaxime Ripard 	{}
1034af34b57SMaxime Ripard };
1044af34b57SMaxime Ripard 
1054af34b57SMaxime Ripard static struct device *sram_dev;
1064af34b57SMaxime Ripard static LIST_HEAD(claimed_sram);
1074af34b57SMaxime Ripard static DEFINE_SPINLOCK(sram_lock);
1084af34b57SMaxime Ripard static void __iomem *base;
1094af34b57SMaxime Ripard 
1104af34b57SMaxime Ripard static int sunxi_sram_show(struct seq_file *s, void *data)
1114af34b57SMaxime Ripard {
1124af34b57SMaxime Ripard 	struct device_node *sram_node, *section_node;
1134af34b57SMaxime Ripard 	const struct sunxi_sram_data *sram_data;
1144af34b57SMaxime Ripard 	const struct of_device_id *match;
1154af34b57SMaxime Ripard 	struct sunxi_sram_func *func;
1164af34b57SMaxime Ripard 	const __be32 *sram_addr_p, *section_addr_p;
1174af34b57SMaxime Ripard 	u32 val;
1184af34b57SMaxime Ripard 
1194af34b57SMaxime Ripard 	seq_puts(s, "Allwinner sunXi SRAM\n");
1204af34b57SMaxime Ripard 	seq_puts(s, "--------------------\n\n");
1214af34b57SMaxime Ripard 
1224af34b57SMaxime Ripard 	for_each_child_of_node(sram_dev->of_node, sram_node) {
1234af34b57SMaxime Ripard 		sram_addr_p = of_get_address(sram_node, 0, NULL, NULL);
1244af34b57SMaxime Ripard 
1254af34b57SMaxime Ripard 		seq_printf(s, "sram@%08x\n",
1264af34b57SMaxime Ripard 			   be32_to_cpu(*sram_addr_p));
1274af34b57SMaxime Ripard 
1284af34b57SMaxime Ripard 		for_each_child_of_node(sram_node, section_node) {
1294af34b57SMaxime Ripard 			match = of_match_node(sunxi_sram_dt_ids, section_node);
1304af34b57SMaxime Ripard 			if (!match)
1314af34b57SMaxime Ripard 				continue;
1324af34b57SMaxime Ripard 			sram_data = match->data;
1334af34b57SMaxime Ripard 
1344af34b57SMaxime Ripard 			section_addr_p = of_get_address(section_node, 0,
1354af34b57SMaxime Ripard 							NULL, NULL);
1364af34b57SMaxime Ripard 
1374af34b57SMaxime Ripard 			seq_printf(s, "\tsection@%04x\t(%s)\n",
1384af34b57SMaxime Ripard 				   be32_to_cpu(*section_addr_p),
1394af34b57SMaxime Ripard 				   sram_data->name);
1404af34b57SMaxime Ripard 
1414af34b57SMaxime Ripard 			val = readl(base + sram_data->reg);
1424af34b57SMaxime Ripard 			val >>= sram_data->offset;
143febe6569SJens Kuske 			val &= GENMASK(sram_data->width - 1, 0);
1444af34b57SMaxime Ripard 
1454af34b57SMaxime Ripard 			for (func = sram_data->func; func->func; func++) {
1464af34b57SMaxime Ripard 				seq_printf(s, "\t\t%s%c\n", func->func,
1478fed2ce9SIcenowy Zheng 					   func->reg_val == val ?
1488fed2ce9SIcenowy Zheng 					   '*' : ' ');
1494af34b57SMaxime Ripard 			}
1504af34b57SMaxime Ripard 		}
1514af34b57SMaxime Ripard 
1524af34b57SMaxime Ripard 		seq_puts(s, "\n");
1534af34b57SMaxime Ripard 	}
1544af34b57SMaxime Ripard 
1554af34b57SMaxime Ripard 	return 0;
1564af34b57SMaxime Ripard }
1574af34b57SMaxime Ripard 
1582a8c9f12SYangtao Li DEFINE_SHOW_ATTRIBUTE(sunxi_sram);
1594af34b57SMaxime Ripard 
1604af34b57SMaxime Ripard static inline struct sunxi_sram_desc *to_sram_desc(const struct sunxi_sram_data *data)
1614af34b57SMaxime Ripard {
1624af34b57SMaxime Ripard 	return container_of(data, struct sunxi_sram_desc, data);
1634af34b57SMaxime Ripard }
1644af34b57SMaxime Ripard 
1654af34b57SMaxime Ripard static const struct sunxi_sram_data *sunxi_sram_of_parse(struct device_node *node,
1668fed2ce9SIcenowy Zheng 							 unsigned int *reg_value)
1674af34b57SMaxime Ripard {
1684af34b57SMaxime Ripard 	const struct of_device_id *match;
1698fed2ce9SIcenowy Zheng 	const struct sunxi_sram_data *data;
1708fed2ce9SIcenowy Zheng 	struct sunxi_sram_func *func;
1714af34b57SMaxime Ripard 	struct of_phandle_args args;
1728fed2ce9SIcenowy Zheng 	u8 val;
1734af34b57SMaxime Ripard 	int ret;
1744af34b57SMaxime Ripard 
1754af34b57SMaxime Ripard 	ret = of_parse_phandle_with_fixed_args(node, "allwinner,sram", 1, 0,
1764af34b57SMaxime Ripard 					       &args);
1774af34b57SMaxime Ripard 	if (ret)
1784af34b57SMaxime Ripard 		return ERR_PTR(ret);
1794af34b57SMaxime Ripard 
1804af34b57SMaxime Ripard 	if (!of_device_is_available(args.np)) {
1814af34b57SMaxime Ripard 		ret = -EBUSY;
1824af34b57SMaxime Ripard 		goto err;
1834af34b57SMaxime Ripard 	}
1844af34b57SMaxime Ripard 
1858fed2ce9SIcenowy Zheng 	val = args.args[0];
1864af34b57SMaxime Ripard 
1874af34b57SMaxime Ripard 	match = of_match_node(sunxi_sram_dt_ids, args.np);
1884af34b57SMaxime Ripard 	if (!match) {
1894af34b57SMaxime Ripard 		ret = -EINVAL;
1904af34b57SMaxime Ripard 		goto err;
1914af34b57SMaxime Ripard 	}
1924af34b57SMaxime Ripard 
1938fed2ce9SIcenowy Zheng 	data = match->data;
1948fed2ce9SIcenowy Zheng 	if (!data) {
1958fed2ce9SIcenowy Zheng 		ret = -EINVAL;
1968fed2ce9SIcenowy Zheng 		goto err;
1971893a2d5SJason Yan 	}
1988fed2ce9SIcenowy Zheng 
1998fed2ce9SIcenowy Zheng 	for (func = data->func; func->func; func++) {
2008fed2ce9SIcenowy Zheng 		if (val == func->val) {
2018fed2ce9SIcenowy Zheng 			if (reg_value)
2028fed2ce9SIcenowy Zheng 				*reg_value = func->reg_val;
2038fed2ce9SIcenowy Zheng 
2048fed2ce9SIcenowy Zheng 			break;
2058fed2ce9SIcenowy Zheng 		}
2068fed2ce9SIcenowy Zheng 	}
2078fed2ce9SIcenowy Zheng 
2088fed2ce9SIcenowy Zheng 	if (!func->func) {
2098fed2ce9SIcenowy Zheng 		ret = -EINVAL;
2108fed2ce9SIcenowy Zheng 		goto err;
2118fed2ce9SIcenowy Zheng 	}
2128fed2ce9SIcenowy Zheng 
2134af34b57SMaxime Ripard 	of_node_put(args.np);
2144af34b57SMaxime Ripard 	return match->data;
2154af34b57SMaxime Ripard 
2164af34b57SMaxime Ripard err:
2174af34b57SMaxime Ripard 	of_node_put(args.np);
2184af34b57SMaxime Ripard 	return ERR_PTR(ret);
2194af34b57SMaxime Ripard }
2204af34b57SMaxime Ripard 
2214af34b57SMaxime Ripard int sunxi_sram_claim(struct device *dev)
2224af34b57SMaxime Ripard {
2234af34b57SMaxime Ripard 	const struct sunxi_sram_data *sram_data;
2244af34b57SMaxime Ripard 	struct sunxi_sram_desc *sram_desc;
2254af34b57SMaxime Ripard 	unsigned int device;
2264af34b57SMaxime Ripard 	u32 val, mask;
2274af34b57SMaxime Ripard 
2284af34b57SMaxime Ripard 	if (IS_ERR(base))
2292262a65fSIcenowy Zheng 		return PTR_ERR(base);
2302262a65fSIcenowy Zheng 
2312262a65fSIcenowy Zheng 	if (!base)
2324af34b57SMaxime Ripard 		return -EPROBE_DEFER;
2334af34b57SMaxime Ripard 
2344af34b57SMaxime Ripard 	if (!dev || !dev->of_node)
2354af34b57SMaxime Ripard 		return -EINVAL;
2364af34b57SMaxime Ripard 
2374af34b57SMaxime Ripard 	sram_data = sunxi_sram_of_parse(dev->of_node, &device);
2384af34b57SMaxime Ripard 	if (IS_ERR(sram_data))
2394af34b57SMaxime Ripard 		return PTR_ERR(sram_data);
2404af34b57SMaxime Ripard 
2414af34b57SMaxime Ripard 	sram_desc = to_sram_desc(sram_data);
2424af34b57SMaxime Ripard 
2434af34b57SMaxime Ripard 	spin_lock(&sram_lock);
2444af34b57SMaxime Ripard 
2454af34b57SMaxime Ripard 	if (sram_desc->claimed) {
2464af34b57SMaxime Ripard 		spin_unlock(&sram_lock);
2474af34b57SMaxime Ripard 		return -EBUSY;
2484af34b57SMaxime Ripard 	}
2494af34b57SMaxime Ripard 
250febe6569SJens Kuske 	mask = GENMASK(sram_data->offset + sram_data->width - 1,
251febe6569SJens Kuske 		       sram_data->offset);
2524af34b57SMaxime Ripard 	val = readl(base + sram_data->reg);
2534af34b57SMaxime Ripard 	val &= ~mask;
2544af34b57SMaxime Ripard 	writel(val | ((device << sram_data->offset) & mask),
2554af34b57SMaxime Ripard 	       base + sram_data->reg);
2564af34b57SMaxime Ripard 
257fd362baaSSamuel Holland 	sram_desc->claimed = true;
2584af34b57SMaxime Ripard 	spin_unlock(&sram_lock);
2594af34b57SMaxime Ripard 
2604af34b57SMaxime Ripard 	return 0;
2614af34b57SMaxime Ripard }
2624af34b57SMaxime Ripard EXPORT_SYMBOL(sunxi_sram_claim);
2634af34b57SMaxime Ripard 
264*460d9cb6SSamuel Holland void sunxi_sram_release(struct device *dev)
2654af34b57SMaxime Ripard {
2664af34b57SMaxime Ripard 	const struct sunxi_sram_data *sram_data;
2674af34b57SMaxime Ripard 	struct sunxi_sram_desc *sram_desc;
2684af34b57SMaxime Ripard 
2694af34b57SMaxime Ripard 	if (!dev || !dev->of_node)
270*460d9cb6SSamuel Holland 		return;
2714af34b57SMaxime Ripard 
2724af34b57SMaxime Ripard 	sram_data = sunxi_sram_of_parse(dev->of_node, NULL);
2734af34b57SMaxime Ripard 	if (IS_ERR(sram_data))
274*460d9cb6SSamuel Holland 		return;
2754af34b57SMaxime Ripard 
2764af34b57SMaxime Ripard 	sram_desc = to_sram_desc(sram_data);
2774af34b57SMaxime Ripard 
2784af34b57SMaxime Ripard 	spin_lock(&sram_lock);
2794af34b57SMaxime Ripard 	sram_desc->claimed = false;
2804af34b57SMaxime Ripard 	spin_unlock(&sram_lock);
2814af34b57SMaxime Ripard }
2824af34b57SMaxime Ripard EXPORT_SYMBOL(sunxi_sram_release);
2834af34b57SMaxime Ripard 
2845828729bSIcenowy Zheng struct sunxi_sramc_variant {
2859117d0c9SAndre Przywara 	int num_emac_clocks;
2865828729bSIcenowy Zheng };
2875828729bSIcenowy Zheng 
2885828729bSIcenowy Zheng static const struct sunxi_sramc_variant sun4i_a10_sramc_variant = {
2895828729bSIcenowy Zheng 	/* Nothing special */
2905828729bSIcenowy Zheng };
2915828729bSIcenowy Zheng 
29215e53723SPaul Kocialkowski static const struct sunxi_sramc_variant sun8i_h3_sramc_variant = {
2939117d0c9SAndre Przywara 	.num_emac_clocks = 1,
29415e53723SPaul Kocialkowski };
29515e53723SPaul Kocialkowski 
2965828729bSIcenowy Zheng static const struct sunxi_sramc_variant sun50i_a64_sramc_variant = {
2979117d0c9SAndre Przywara 	.num_emac_clocks = 1,
2989117d0c9SAndre Przywara };
2999117d0c9SAndre Przywara 
3009117d0c9SAndre Przywara static const struct sunxi_sramc_variant sun50i_h616_sramc_variant = {
3019117d0c9SAndre Przywara 	.num_emac_clocks = 2,
3025828729bSIcenowy Zheng };
3035828729bSIcenowy Zheng 
3045828729bSIcenowy Zheng #define SUNXI_SRAM_EMAC_CLOCK_REG	0x30
3055828729bSIcenowy Zheng static bool sunxi_sram_regmap_accessible_reg(struct device *dev,
3065828729bSIcenowy Zheng 					     unsigned int reg)
3075828729bSIcenowy Zheng {
3089117d0c9SAndre Przywara 	const struct sunxi_sramc_variant *variant;
3099117d0c9SAndre Przywara 
3109117d0c9SAndre Przywara 	variant = of_device_get_match_data(dev);
3119117d0c9SAndre Przywara 
3129117d0c9SAndre Przywara 	if (reg < SUNXI_SRAM_EMAC_CLOCK_REG)
3135828729bSIcenowy Zheng 		return false;
3149117d0c9SAndre Przywara 	if (reg > SUNXI_SRAM_EMAC_CLOCK_REG + variant->num_emac_clocks * 4)
3159117d0c9SAndre Przywara 		return false;
3169117d0c9SAndre Przywara 
3179117d0c9SAndre Przywara 	return true;
3185828729bSIcenowy Zheng }
3195828729bSIcenowy Zheng 
3205828729bSIcenowy Zheng static struct regmap_config sunxi_sram_emac_clock_regmap = {
3215828729bSIcenowy Zheng 	.reg_bits       = 32,
3225828729bSIcenowy Zheng 	.val_bits       = 32,
3235828729bSIcenowy Zheng 	.reg_stride     = 4,
3245828729bSIcenowy Zheng 	/* last defined register */
3259117d0c9SAndre Przywara 	.max_register   = SUNXI_SRAM_EMAC_CLOCK_REG + 4,
3265828729bSIcenowy Zheng 	/* other devices have no business accessing other registers */
3275828729bSIcenowy Zheng 	.readable_reg	= sunxi_sram_regmap_accessible_reg,
3285828729bSIcenowy Zheng 	.writeable_reg	= sunxi_sram_regmap_accessible_reg,
3295828729bSIcenowy Zheng };
3305828729bSIcenowy Zheng 
33190e10a1fSSamuel Holland static int __init sunxi_sram_probe(struct platform_device *pdev)
3324af34b57SMaxime Ripard {
3335828729bSIcenowy Zheng 	struct regmap *emac_clock;
3345828729bSIcenowy Zheng 	const struct sunxi_sramc_variant *variant;
33549fad91aSSamuel Holland 	struct device *dev = &pdev->dev;
3364af34b57SMaxime Ripard 
3374af34b57SMaxime Ripard 	sram_dev = &pdev->dev;
3384af34b57SMaxime Ripard 
3395828729bSIcenowy Zheng 	variant = of_device_get_match_data(&pdev->dev);
3405828729bSIcenowy Zheng 	if (!variant)
3415828729bSIcenowy Zheng 		return -EINVAL;
3425828729bSIcenowy Zheng 
3431f3753a5SCai Huoqing 	base = devm_platform_ioremap_resource(pdev, 0);
3444af34b57SMaxime Ripard 	if (IS_ERR(base))
3454af34b57SMaxime Ripard 		return PTR_ERR(base);
3464af34b57SMaxime Ripard 
3479117d0c9SAndre Przywara 	if (variant->num_emac_clocks > 0) {
3485828729bSIcenowy Zheng 		emac_clock = devm_regmap_init_mmio(&pdev->dev, base,
3495828729bSIcenowy Zheng 						   &sunxi_sram_emac_clock_regmap);
3505828729bSIcenowy Zheng 
3515828729bSIcenowy Zheng 		if (IS_ERR(emac_clock))
3525828729bSIcenowy Zheng 			return PTR_ERR(emac_clock);
3535828729bSIcenowy Zheng 	}
3545828729bSIcenowy Zheng 
35549fad91aSSamuel Holland 	of_platform_populate(dev->of_node, NULL, NULL, dev);
35649fad91aSSamuel Holland 
35749fad91aSSamuel Holland 	debugfs_create_file("sram", 0444, NULL, NULL, &sunxi_sram_fops);
35849fad91aSSamuel Holland 
3594af34b57SMaxime Ripard 	return 0;
3604af34b57SMaxime Ripard }
3614af34b57SMaxime Ripard 
3624af34b57SMaxime Ripard static const struct of_device_id sunxi_sram_dt_match[] = {
3635828729bSIcenowy Zheng 	{
3645828729bSIcenowy Zheng 		.compatible = "allwinner,sun4i-a10-sram-controller",
3655828729bSIcenowy Zheng 		.data = &sun4i_a10_sramc_variant,
3665828729bSIcenowy Zheng 	},
3675828729bSIcenowy Zheng 	{
368acc26f59SPaul Kocialkowski 		.compatible = "allwinner,sun4i-a10-system-control",
369acc26f59SPaul Kocialkowski 		.data = &sun4i_a10_sramc_variant,
370acc26f59SPaul Kocialkowski 	},
371acc26f59SPaul Kocialkowski 	{
3727377330aSMaxime Ripard 		.compatible = "allwinner,sun5i-a13-system-control",
3737377330aSMaxime Ripard 		.data = &sun4i_a10_sramc_variant,
3747377330aSMaxime Ripard 	},
3757377330aSMaxime Ripard 	{
3767377330aSMaxime Ripard 		.compatible = "allwinner,sun8i-a23-system-control",
3777377330aSMaxime Ripard 		.data = &sun4i_a10_sramc_variant,
3787377330aSMaxime Ripard 	},
3797377330aSMaxime Ripard 	{
3807377330aSMaxime Ripard 		.compatible = "allwinner,sun8i-h3-system-control",
38115e53723SPaul Kocialkowski 		.data = &sun8i_h3_sramc_variant,
3827377330aSMaxime Ripard 	},
3837377330aSMaxime Ripard 	{
3845828729bSIcenowy Zheng 		.compatible = "allwinner,sun50i-a64-sram-controller",
3855828729bSIcenowy Zheng 		.data = &sun50i_a64_sramc_variant,
3865828729bSIcenowy Zheng 	},
387ede18ae3SChen-Yu Tsai 	{
388ede18ae3SChen-Yu Tsai 		.compatible = "allwinner,sun50i-a64-system-control",
389ede18ae3SChen-Yu Tsai 		.data = &sun50i_a64_sramc_variant,
390ede18ae3SChen-Yu Tsai 	},
391c7739268SPaul Kocialkowski 	{
392c7739268SPaul Kocialkowski 		.compatible = "allwinner,sun50i-h5-system-control",
393c7739268SPaul Kocialkowski 		.data = &sun50i_a64_sramc_variant,
394c7739268SPaul Kocialkowski 	},
3959117d0c9SAndre Przywara 	{
3969117d0c9SAndre Przywara 		.compatible = "allwinner,sun50i-h616-system-control",
3979117d0c9SAndre Przywara 		.data = &sun50i_h616_sramc_variant,
3989117d0c9SAndre Przywara 	},
3994af34b57SMaxime Ripard 	{ },
4004af34b57SMaxime Ripard };
4014af34b57SMaxime Ripard MODULE_DEVICE_TABLE(of, sunxi_sram_dt_match);
4024af34b57SMaxime Ripard 
4034af34b57SMaxime Ripard static struct platform_driver sunxi_sram_driver = {
4044af34b57SMaxime Ripard 	.driver = {
4054af34b57SMaxime Ripard 		.name		= "sunxi-sram",
4064af34b57SMaxime Ripard 		.of_match_table	= sunxi_sram_dt_match,
4074af34b57SMaxime Ripard 	},
4084af34b57SMaxime Ripard };
40990e10a1fSSamuel Holland builtin_platform_driver_probe(sunxi_sram_driver, sunxi_sram_probe);
4104af34b57SMaxime Ripard 
4114af34b57SMaxime Ripard MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com>");
4124af34b57SMaxime Ripard MODULE_DESCRIPTION("Allwinner sunXi SRAM Controller Driver");
4134af34b57SMaxime Ripard MODULE_LICENSE("GPL");
414