• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  */
c6x_emifa_init(void)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);
85