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>
18*23e9bf8eSRob Herring #include <linux/of_platform.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
sunxi_sram_show(struct seq_file * s,void * data)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) {
12373b7d7f2SSamuel Holland if (!of_device_is_compatible(sram_node, "mmio-sram"))
12473b7d7f2SSamuel Holland continue;
12573b7d7f2SSamuel Holland
1264af34b57SMaxime Ripard sram_addr_p = of_get_address(sram_node, 0, NULL, NULL);
1274af34b57SMaxime Ripard
1284af34b57SMaxime Ripard seq_printf(s, "sram@%08x\n",
1294af34b57SMaxime Ripard be32_to_cpu(*sram_addr_p));
1304af34b57SMaxime Ripard
1314af34b57SMaxime Ripard for_each_child_of_node(sram_node, section_node) {
1324af34b57SMaxime Ripard match = of_match_node(sunxi_sram_dt_ids, section_node);
1334af34b57SMaxime Ripard if (!match)
1344af34b57SMaxime Ripard continue;
1354af34b57SMaxime Ripard sram_data = match->data;
1364af34b57SMaxime Ripard
1374af34b57SMaxime Ripard section_addr_p = of_get_address(section_node, 0,
1384af34b57SMaxime Ripard NULL, NULL);
1394af34b57SMaxime Ripard
1404af34b57SMaxime Ripard seq_printf(s, "\tsection@%04x\t(%s)\n",
1414af34b57SMaxime Ripard be32_to_cpu(*section_addr_p),
1424af34b57SMaxime Ripard sram_data->name);
1434af34b57SMaxime Ripard
1444af34b57SMaxime Ripard val = readl(base + sram_data->reg);
1454af34b57SMaxime Ripard val >>= sram_data->offset;
146febe6569SJens Kuske val &= GENMASK(sram_data->width - 1, 0);
1474af34b57SMaxime Ripard
1484af34b57SMaxime Ripard for (func = sram_data->func; func->func; func++) {
1494af34b57SMaxime Ripard seq_printf(s, "\t\t%s%c\n", func->func,
1508fed2ce9SIcenowy Zheng func->reg_val == val ?
1518fed2ce9SIcenowy Zheng '*' : ' ');
1524af34b57SMaxime Ripard }
1534af34b57SMaxime Ripard }
1544af34b57SMaxime Ripard
1554af34b57SMaxime Ripard seq_puts(s, "\n");
1564af34b57SMaxime Ripard }
1574af34b57SMaxime Ripard
1584af34b57SMaxime Ripard return 0;
1594af34b57SMaxime Ripard }
1604af34b57SMaxime Ripard
1612a8c9f12SYangtao Li DEFINE_SHOW_ATTRIBUTE(sunxi_sram);
1624af34b57SMaxime Ripard
to_sram_desc(const struct sunxi_sram_data * data)1634af34b57SMaxime Ripard static inline struct sunxi_sram_desc *to_sram_desc(const struct sunxi_sram_data *data)
1644af34b57SMaxime Ripard {
1654af34b57SMaxime Ripard return container_of(data, struct sunxi_sram_desc, data);
1664af34b57SMaxime Ripard }
1674af34b57SMaxime Ripard
sunxi_sram_of_parse(struct device_node * node,unsigned int * reg_value)1684af34b57SMaxime Ripard static const struct sunxi_sram_data *sunxi_sram_of_parse(struct device_node *node,
1698fed2ce9SIcenowy Zheng unsigned int *reg_value)
1704af34b57SMaxime Ripard {
1714af34b57SMaxime Ripard const struct of_device_id *match;
1728fed2ce9SIcenowy Zheng const struct sunxi_sram_data *data;
1738fed2ce9SIcenowy Zheng struct sunxi_sram_func *func;
1744af34b57SMaxime Ripard struct of_phandle_args args;
1758fed2ce9SIcenowy Zheng u8 val;
1764af34b57SMaxime Ripard int ret;
1774af34b57SMaxime Ripard
1784af34b57SMaxime Ripard ret = of_parse_phandle_with_fixed_args(node, "allwinner,sram", 1, 0,
1794af34b57SMaxime Ripard &args);
1804af34b57SMaxime Ripard if (ret)
1814af34b57SMaxime Ripard return ERR_PTR(ret);
1824af34b57SMaxime Ripard
1834af34b57SMaxime Ripard if (!of_device_is_available(args.np)) {
1844af34b57SMaxime Ripard ret = -EBUSY;
1854af34b57SMaxime Ripard goto err;
1864af34b57SMaxime Ripard }
1874af34b57SMaxime Ripard
1888fed2ce9SIcenowy Zheng val = args.args[0];
1894af34b57SMaxime Ripard
1904af34b57SMaxime Ripard match = of_match_node(sunxi_sram_dt_ids, args.np);
1914af34b57SMaxime Ripard if (!match) {
1924af34b57SMaxime Ripard ret = -EINVAL;
1934af34b57SMaxime Ripard goto err;
1944af34b57SMaxime Ripard }
1954af34b57SMaxime Ripard
1968fed2ce9SIcenowy Zheng data = match->data;
1978fed2ce9SIcenowy Zheng if (!data) {
1988fed2ce9SIcenowy Zheng ret = -EINVAL;
1998fed2ce9SIcenowy Zheng goto err;
2001893a2d5SJason Yan }
2018fed2ce9SIcenowy Zheng
2028fed2ce9SIcenowy Zheng for (func = data->func; func->func; func++) {
2038fed2ce9SIcenowy Zheng if (val == func->val) {
2048fed2ce9SIcenowy Zheng if (reg_value)
2058fed2ce9SIcenowy Zheng *reg_value = func->reg_val;
2068fed2ce9SIcenowy Zheng
2078fed2ce9SIcenowy Zheng break;
2088fed2ce9SIcenowy Zheng }
2098fed2ce9SIcenowy Zheng }
2108fed2ce9SIcenowy Zheng
2118fed2ce9SIcenowy Zheng if (!func->func) {
2128fed2ce9SIcenowy Zheng ret = -EINVAL;
2138fed2ce9SIcenowy Zheng goto err;
2148fed2ce9SIcenowy Zheng }
2158fed2ce9SIcenowy Zheng
2164af34b57SMaxime Ripard of_node_put(args.np);
2174af34b57SMaxime Ripard return match->data;
2184af34b57SMaxime Ripard
2194af34b57SMaxime Ripard err:
2204af34b57SMaxime Ripard of_node_put(args.np);
2214af34b57SMaxime Ripard return ERR_PTR(ret);
2224af34b57SMaxime Ripard }
2234af34b57SMaxime Ripard
sunxi_sram_claim(struct device * dev)2244af34b57SMaxime Ripard int sunxi_sram_claim(struct device *dev)
2254af34b57SMaxime Ripard {
2264af34b57SMaxime Ripard const struct sunxi_sram_data *sram_data;
2274af34b57SMaxime Ripard struct sunxi_sram_desc *sram_desc;
2284af34b57SMaxime Ripard unsigned int device;
2294af34b57SMaxime Ripard u32 val, mask;
2304af34b57SMaxime Ripard
2314af34b57SMaxime Ripard if (IS_ERR(base))
2322262a65fSIcenowy Zheng return PTR_ERR(base);
2332262a65fSIcenowy Zheng
2342262a65fSIcenowy Zheng if (!base)
2354af34b57SMaxime Ripard return -EPROBE_DEFER;
2364af34b57SMaxime Ripard
2374af34b57SMaxime Ripard if (!dev || !dev->of_node)
2384af34b57SMaxime Ripard return -EINVAL;
2394af34b57SMaxime Ripard
2404af34b57SMaxime Ripard sram_data = sunxi_sram_of_parse(dev->of_node, &device);
2414af34b57SMaxime Ripard if (IS_ERR(sram_data))
2424af34b57SMaxime Ripard return PTR_ERR(sram_data);
2434af34b57SMaxime Ripard
2444af34b57SMaxime Ripard sram_desc = to_sram_desc(sram_data);
2454af34b57SMaxime Ripard
2464af34b57SMaxime Ripard spin_lock(&sram_lock);
2474af34b57SMaxime Ripard
2484af34b57SMaxime Ripard if (sram_desc->claimed) {
2494af34b57SMaxime Ripard spin_unlock(&sram_lock);
2504af34b57SMaxime Ripard return -EBUSY;
2514af34b57SMaxime Ripard }
2524af34b57SMaxime Ripard
253febe6569SJens Kuske mask = GENMASK(sram_data->offset + sram_data->width - 1,
254febe6569SJens Kuske sram_data->offset);
2554af34b57SMaxime Ripard val = readl(base + sram_data->reg);
2564af34b57SMaxime Ripard val &= ~mask;
2574af34b57SMaxime Ripard writel(val | ((device << sram_data->offset) & mask),
2584af34b57SMaxime Ripard base + sram_data->reg);
2594af34b57SMaxime Ripard
260fd362baaSSamuel Holland sram_desc->claimed = true;
2614af34b57SMaxime Ripard spin_unlock(&sram_lock);
2624af34b57SMaxime Ripard
2634af34b57SMaxime Ripard return 0;
2644af34b57SMaxime Ripard }
2654af34b57SMaxime Ripard EXPORT_SYMBOL(sunxi_sram_claim);
2664af34b57SMaxime Ripard
sunxi_sram_release(struct device * dev)267460d9cb6SSamuel Holland void sunxi_sram_release(struct device *dev)
2684af34b57SMaxime Ripard {
2694af34b57SMaxime Ripard const struct sunxi_sram_data *sram_data;
2704af34b57SMaxime Ripard struct sunxi_sram_desc *sram_desc;
2714af34b57SMaxime Ripard
2724af34b57SMaxime Ripard if (!dev || !dev->of_node)
273460d9cb6SSamuel Holland return;
2744af34b57SMaxime Ripard
2754af34b57SMaxime Ripard sram_data = sunxi_sram_of_parse(dev->of_node, NULL);
2764af34b57SMaxime Ripard if (IS_ERR(sram_data))
277460d9cb6SSamuel Holland return;
2784af34b57SMaxime Ripard
2794af34b57SMaxime Ripard sram_desc = to_sram_desc(sram_data);
2804af34b57SMaxime Ripard
2814af34b57SMaxime Ripard spin_lock(&sram_lock);
2824af34b57SMaxime Ripard sram_desc->claimed = false;
2834af34b57SMaxime Ripard spin_unlock(&sram_lock);
2844af34b57SMaxime Ripard }
2854af34b57SMaxime Ripard EXPORT_SYMBOL(sunxi_sram_release);
2864af34b57SMaxime Ripard
2875828729bSIcenowy Zheng struct sunxi_sramc_variant {
2889117d0c9SAndre Przywara int num_emac_clocks;
289dd2ae2ecSSamuel Holland bool has_ldo_ctrl;
2905828729bSIcenowy Zheng };
2915828729bSIcenowy Zheng
2925828729bSIcenowy Zheng static const struct sunxi_sramc_variant sun4i_a10_sramc_variant = {
2935828729bSIcenowy Zheng /* Nothing special */
2945828729bSIcenowy Zheng };
2955828729bSIcenowy Zheng
29615e53723SPaul Kocialkowski static const struct sunxi_sramc_variant sun8i_h3_sramc_variant = {
2979117d0c9SAndre Przywara .num_emac_clocks = 1,
29815e53723SPaul Kocialkowski };
29915e53723SPaul Kocialkowski
3001f698cb1SSamuel Holland static const struct sunxi_sramc_variant sun20i_d1_sramc_variant = {
3011f698cb1SSamuel Holland .num_emac_clocks = 1,
3021f698cb1SSamuel Holland .has_ldo_ctrl = true,
3031f698cb1SSamuel Holland };
3041f698cb1SSamuel Holland
3055828729bSIcenowy Zheng static const struct sunxi_sramc_variant sun50i_a64_sramc_variant = {
3069117d0c9SAndre Przywara .num_emac_clocks = 1,
3079117d0c9SAndre Przywara };
3089117d0c9SAndre Przywara
3099117d0c9SAndre Przywara static const struct sunxi_sramc_variant sun50i_h616_sramc_variant = {
3109117d0c9SAndre Przywara .num_emac_clocks = 2,
3115828729bSIcenowy Zheng };
3125828729bSIcenowy Zheng
3135828729bSIcenowy Zheng #define SUNXI_SRAM_EMAC_CLOCK_REG 0x30
314dd2ae2ecSSamuel Holland #define SUNXI_SYS_LDO_CTRL_REG 0x150
315dd2ae2ecSSamuel Holland
sunxi_sram_regmap_accessible_reg(struct device * dev,unsigned int reg)3165828729bSIcenowy Zheng static bool sunxi_sram_regmap_accessible_reg(struct device *dev,
3175828729bSIcenowy Zheng unsigned int reg)
3185828729bSIcenowy Zheng {
319ee07b905SSamuel Holland const struct sunxi_sramc_variant *variant = dev_get_drvdata(dev);
3209117d0c9SAndre Przywara
321dd2ae2ecSSamuel Holland if (reg >= SUNXI_SRAM_EMAC_CLOCK_REG &&
322dd2ae2ecSSamuel Holland reg < SUNXI_SRAM_EMAC_CLOCK_REG + variant->num_emac_clocks * 4)
3239117d0c9SAndre Przywara return true;
324dd2ae2ecSSamuel Holland if (reg == SUNXI_SYS_LDO_CTRL_REG && variant->has_ldo_ctrl)
325dd2ae2ecSSamuel Holland return true;
326dd2ae2ecSSamuel Holland
327dd2ae2ecSSamuel Holland return false;
3285828729bSIcenowy Zheng }
3295828729bSIcenowy Zheng
330dd2ae2ecSSamuel Holland static struct regmap_config sunxi_sram_regmap_config = {
3315828729bSIcenowy Zheng .reg_bits = 32,
3325828729bSIcenowy Zheng .val_bits = 32,
3335828729bSIcenowy Zheng .reg_stride = 4,
3345828729bSIcenowy Zheng /* last defined register */
335dd2ae2ecSSamuel Holland .max_register = SUNXI_SYS_LDO_CTRL_REG,
3365828729bSIcenowy Zheng /* other devices have no business accessing other registers */
3375828729bSIcenowy Zheng .readable_reg = sunxi_sram_regmap_accessible_reg,
3385828729bSIcenowy Zheng .writeable_reg = sunxi_sram_regmap_accessible_reg,
3395828729bSIcenowy Zheng };
3405828729bSIcenowy Zheng
sunxi_sram_probe(struct platform_device * pdev)34190e10a1fSSamuel Holland static int __init sunxi_sram_probe(struct platform_device *pdev)
3424af34b57SMaxime Ripard {
3435828729bSIcenowy Zheng const struct sunxi_sramc_variant *variant;
34449fad91aSSamuel Holland struct device *dev = &pdev->dev;
345dd2ae2ecSSamuel Holland struct regmap *regmap;
3464af34b57SMaxime Ripard
3474af34b57SMaxime Ripard sram_dev = &pdev->dev;
3484af34b57SMaxime Ripard
3495828729bSIcenowy Zheng variant = of_device_get_match_data(&pdev->dev);
3505828729bSIcenowy Zheng if (!variant)
3515828729bSIcenowy Zheng return -EINVAL;
3525828729bSIcenowy Zheng
353ee07b905SSamuel Holland dev_set_drvdata(dev, (struct sunxi_sramc_variant *)variant);
354ee07b905SSamuel Holland
3551f3753a5SCai Huoqing base = devm_platform_ioremap_resource(pdev, 0);
3564af34b57SMaxime Ripard if (IS_ERR(base))
3574af34b57SMaxime Ripard return PTR_ERR(base);
3584af34b57SMaxime Ripard
359dd2ae2ecSSamuel Holland if (variant->num_emac_clocks || variant->has_ldo_ctrl) {
360dd2ae2ecSSamuel Holland regmap = devm_regmap_init_mmio(dev, base, &sunxi_sram_regmap_config);
361dd2ae2ecSSamuel Holland if (IS_ERR(regmap))
362dd2ae2ecSSamuel Holland return PTR_ERR(regmap);
3635828729bSIcenowy Zheng }
3645828729bSIcenowy Zheng
36549fad91aSSamuel Holland of_platform_populate(dev->of_node, NULL, NULL, dev);
36649fad91aSSamuel Holland
36749fad91aSSamuel Holland debugfs_create_file("sram", 0444, NULL, NULL, &sunxi_sram_fops);
36849fad91aSSamuel Holland
3694af34b57SMaxime Ripard return 0;
3704af34b57SMaxime Ripard }
3714af34b57SMaxime Ripard
3724af34b57SMaxime Ripard static const struct of_device_id sunxi_sram_dt_match[] = {
3735828729bSIcenowy Zheng {
3745828729bSIcenowy Zheng .compatible = "allwinner,sun4i-a10-sram-controller",
3755828729bSIcenowy Zheng .data = &sun4i_a10_sramc_variant,
3765828729bSIcenowy Zheng },
3775828729bSIcenowy Zheng {
378acc26f59SPaul Kocialkowski .compatible = "allwinner,sun4i-a10-system-control",
379acc26f59SPaul Kocialkowski .data = &sun4i_a10_sramc_variant,
380acc26f59SPaul Kocialkowski },
381acc26f59SPaul Kocialkowski {
3827377330aSMaxime Ripard .compatible = "allwinner,sun5i-a13-system-control",
3837377330aSMaxime Ripard .data = &sun4i_a10_sramc_variant,
3847377330aSMaxime Ripard },
3857377330aSMaxime Ripard {
3867377330aSMaxime Ripard .compatible = "allwinner,sun8i-a23-system-control",
3877377330aSMaxime Ripard .data = &sun4i_a10_sramc_variant,
3887377330aSMaxime Ripard },
3897377330aSMaxime Ripard {
3907377330aSMaxime Ripard .compatible = "allwinner,sun8i-h3-system-control",
39115e53723SPaul Kocialkowski .data = &sun8i_h3_sramc_variant,
3927377330aSMaxime Ripard },
3937377330aSMaxime Ripard {
3941f698cb1SSamuel Holland .compatible = "allwinner,sun20i-d1-system-control",
3951f698cb1SSamuel Holland .data = &sun20i_d1_sramc_variant,
3961f698cb1SSamuel Holland },
3971f698cb1SSamuel Holland {
3985828729bSIcenowy Zheng .compatible = "allwinner,sun50i-a64-sram-controller",
3995828729bSIcenowy Zheng .data = &sun50i_a64_sramc_variant,
4005828729bSIcenowy Zheng },
401ede18ae3SChen-Yu Tsai {
402ede18ae3SChen-Yu Tsai .compatible = "allwinner,sun50i-a64-system-control",
403ede18ae3SChen-Yu Tsai .data = &sun50i_a64_sramc_variant,
404ede18ae3SChen-Yu Tsai },
405c7739268SPaul Kocialkowski {
406c7739268SPaul Kocialkowski .compatible = "allwinner,sun50i-h5-system-control",
407c7739268SPaul Kocialkowski .data = &sun50i_a64_sramc_variant,
408c7739268SPaul Kocialkowski },
4099117d0c9SAndre Przywara {
4109117d0c9SAndre Przywara .compatible = "allwinner,sun50i-h616-system-control",
4119117d0c9SAndre Przywara .data = &sun50i_h616_sramc_variant,
4129117d0c9SAndre Przywara },
4134af34b57SMaxime Ripard { },
4144af34b57SMaxime Ripard };
4154af34b57SMaxime Ripard MODULE_DEVICE_TABLE(of, sunxi_sram_dt_match);
4164af34b57SMaxime Ripard
4174af34b57SMaxime Ripard static struct platform_driver sunxi_sram_driver = {
4184af34b57SMaxime Ripard .driver = {
4194af34b57SMaxime Ripard .name = "sunxi-sram",
4204af34b57SMaxime Ripard .of_match_table = sunxi_sram_dt_match,
4214af34b57SMaxime Ripard },
4224af34b57SMaxime Ripard };
42390e10a1fSSamuel Holland builtin_platform_driver_probe(sunxi_sram_driver, sunxi_sram_probe);
4244af34b57SMaxime Ripard
4254af34b57SMaxime Ripard MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com>");
4264af34b57SMaxime Ripard MODULE_DESCRIPTION("Allwinner sunXi SRAM Controller Driver");
427