88 lines
		
	
	
	
		
			2 KiB
			
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			88 lines
		
	
	
	
		
			2 KiB
			
		
	
	
	
		
			C
		
	
	
	
	
	
|   | /*
 | ||
|  |  *  External Memory Interface | ||
|  |  * | ||
|  |  *  Copyright (C) 2011 Texas Instruments Incorporated | ||
|  |  *  Author: Mark Salter <msalter@redhat.com> | ||
|  |  * | ||
|  |  *  This program is free software; you can redistribute it and/or modify | ||
|  |  *  it under the terms of the GNU General Public License version 2 as | ||
|  |  *  published by the Free Software Foundation. | ||
|  |  */ | ||
|  | #include <linux/of.h>
 | ||
|  | #include <linux/of_address.h>
 | ||
|  | #include <linux/io.h>
 | ||
|  | #include <asm/soc.h>
 | ||
|  | #include <asm/dscr.h>
 | ||
|  | 
 | ||
|  | #define NUM_EMIFA_CHIP_ENABLES 4
 | ||
|  | 
 | ||
|  | struct emifa_regs { | ||
|  | 	u32	midr; | ||
|  | 	u32	stat; | ||
|  | 	u32	reserved1[6]; | ||
|  | 	u32	bprio; | ||
|  | 	u32	reserved2[23]; | ||
|  | 	u32	cecfg[NUM_EMIFA_CHIP_ENABLES]; | ||
|  | 	u32	reserved3[4]; | ||
|  | 	u32	awcc; | ||
|  | 	u32	reserved4[7]; | ||
|  | 	u32	intraw; | ||
|  | 	u32	intmsk; | ||
|  | 	u32	intmskset; | ||
|  | 	u32	intmskclr; | ||
|  | }; | ||
|  | 
 | ||
|  | static struct of_device_id emifa_match[] __initdata = { | ||
|  | 	{ .compatible = "ti,c64x+emifa"	}, | ||
|  | 	{} | ||
|  | }; | ||
|  | 
 | ||
|  | /*
 | ||
|  |  * Parse device tree for existence of an EMIF (External Memory Interface) | ||
|  |  * and initialize it if found. | ||
|  |  */ | ||
|  | static int __init c6x_emifa_init(void) | ||
|  | { | ||
|  | 	struct emifa_regs __iomem *regs; | ||
|  | 	struct device_node *node; | ||
|  | 	const __be32 *p; | ||
|  | 	u32 val; | ||
|  | 	int i, len, err; | ||
|  | 
 | ||
|  | 	node = of_find_matching_node(NULL, emifa_match); | ||
|  | 	if (!node) | ||
|  | 		return 0; | ||
|  | 
 | ||
|  | 	regs = of_iomap(node, 0); | ||
|  | 	if (!regs) | ||
|  | 		return 0; | ||
|  | 
 | ||
|  | 	/* look for a dscr-based enable for emifa pin buffers */ | ||
|  | 	err = of_property_read_u32_array(node, "ti,dscr-dev-enable", &val, 1); | ||
|  | 	if (!err) | ||
|  | 		dscr_set_devstate(val, DSCR_DEVSTATE_ENABLED); | ||
|  | 
 | ||
|  | 	/* set up the chip enables */ | ||
|  | 	p = of_get_property(node, "ti,emifa-ce-config", &len); | ||
|  | 	if (p) { | ||
|  | 		len /= sizeof(u32); | ||
|  | 		if (len > NUM_EMIFA_CHIP_ENABLES) | ||
|  | 			len = NUM_EMIFA_CHIP_ENABLES; | ||
|  | 		for (i = 0; i <= len; i++) | ||
|  | 			soc_writel(be32_to_cpup(&p[i]), ®s->cecfg[i]); | ||
|  | 	} | ||
|  | 
 | ||
|  | 	err = of_property_read_u32_array(node, "ti,emifa-burst-priority", &val, 1); | ||
|  | 	if (!err) | ||
|  | 		soc_writel(val, ®s->bprio); | ||
|  | 
 | ||
|  | 	err = of_property_read_u32_array(node, "ti,emifa-async-wait-control", &val, 1); | ||
|  | 	if (!err) | ||
|  | 		soc_writel(val, ®s->awcc); | ||
|  | 
 | ||
|  | 	iounmap(regs); | ||
|  | 	of_node_put(node); | ||
|  | 	return 0; | ||
|  | } | ||
|  | pure_initcall(c6x_emifa_init); |