Merge tag 'mips_5.3' of git://git.kernel.org/pub/scm/linux/kernel/git/mips/linux
[linux-2.6-microblaze.git] / arch / c6x / platforms / emif.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  *  External Memory Interface
4  *
5  *  Copyright (C) 2011 Texas Instruments Incorporated
6  *  Author: Mark Salter <msalter@redhat.com>
7  */
8 #include <linux/of.h>
9 #include <linux/of_address.h>
10 #include <linux/io.h>
11 #include <asm/soc.h>
12 #include <asm/dscr.h>
13
14 #define NUM_EMIFA_CHIP_ENABLES 4
15
16 struct emifa_regs {
17         u32     midr;
18         u32     stat;
19         u32     reserved1[6];
20         u32     bprio;
21         u32     reserved2[23];
22         u32     cecfg[NUM_EMIFA_CHIP_ENABLES];
23         u32     reserved3[4];
24         u32     awcc;
25         u32     reserved4[7];
26         u32     intraw;
27         u32     intmsk;
28         u32     intmskset;
29         u32     intmskclr;
30 };
31
32 static struct of_device_id emifa_match[] __initdata = {
33         { .compatible = "ti,c64x+emifa" },
34         {}
35 };
36
37 /*
38  * Parse device tree for existence of an EMIF (External Memory Interface)
39  * and initialize it if found.
40  */
41 static int __init c6x_emifa_init(void)
42 {
43         struct emifa_regs __iomem *regs;
44         struct device_node *node;
45         const __be32 *p;
46         u32 val;
47         int i, len, err;
48
49         node = of_find_matching_node(NULL, emifa_match);
50         if (!node)
51                 return 0;
52
53         regs = of_iomap(node, 0);
54         if (!regs)
55                 return 0;
56
57         /* look for a dscr-based enable for emifa pin buffers */
58         err = of_property_read_u32_array(node, "ti,dscr-dev-enable", &val, 1);
59         if (!err)
60                 dscr_set_devstate(val, DSCR_DEVSTATE_ENABLED);
61
62         /* set up the chip enables */
63         p = of_get_property(node, "ti,emifa-ce-config", &len);
64         if (p) {
65                 len /= sizeof(u32);
66                 if (len > NUM_EMIFA_CHIP_ENABLES)
67                         len = NUM_EMIFA_CHIP_ENABLES;
68                 for (i = 0; i <= len; i++)
69                         soc_writel(be32_to_cpup(&p[i]), &regs->cecfg[i]);
70         }
71
72         err = of_property_read_u32_array(node, "ti,emifa-burst-priority", &val, 1);
73         if (!err)
74                 soc_writel(val, &regs->bprio);
75
76         err = of_property_read_u32_array(node, "ti,emifa-async-wait-control", &val, 1);
77         if (!err)
78                 soc_writel(val, &regs->awcc);
79
80         iounmap(regs);
81         of_node_put(node);
82         return 0;
83 }
84 pure_initcall(c6x_emifa_init);