18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * External Memory Interface 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Copyright (C) 2011 Texas Instruments Incorporated 68c2ecf20Sopenharmony_ci * Author: Mark Salter <msalter@redhat.com> 78c2ecf20Sopenharmony_ci */ 88c2ecf20Sopenharmony_ci#include <linux/of.h> 98c2ecf20Sopenharmony_ci#include <linux/of_address.h> 108c2ecf20Sopenharmony_ci#include <linux/io.h> 118c2ecf20Sopenharmony_ci#include <asm/soc.h> 128c2ecf20Sopenharmony_ci#include <asm/dscr.h> 138c2ecf20Sopenharmony_ci 148c2ecf20Sopenharmony_ci#define NUM_EMIFA_CHIP_ENABLES 4 158c2ecf20Sopenharmony_ci 168c2ecf20Sopenharmony_cistruct emifa_regs { 178c2ecf20Sopenharmony_ci u32 midr; 188c2ecf20Sopenharmony_ci u32 stat; 198c2ecf20Sopenharmony_ci u32 reserved1[6]; 208c2ecf20Sopenharmony_ci u32 bprio; 218c2ecf20Sopenharmony_ci u32 reserved2[23]; 228c2ecf20Sopenharmony_ci u32 cecfg[NUM_EMIFA_CHIP_ENABLES]; 238c2ecf20Sopenharmony_ci u32 reserved3[4]; 248c2ecf20Sopenharmony_ci u32 awcc; 258c2ecf20Sopenharmony_ci u32 reserved4[7]; 268c2ecf20Sopenharmony_ci u32 intraw; 278c2ecf20Sopenharmony_ci u32 intmsk; 288c2ecf20Sopenharmony_ci u32 intmskset; 298c2ecf20Sopenharmony_ci u32 intmskclr; 308c2ecf20Sopenharmony_ci}; 318c2ecf20Sopenharmony_ci 328c2ecf20Sopenharmony_cistatic struct of_device_id emifa_match[] __initdata = { 338c2ecf20Sopenharmony_ci { .compatible = "ti,c64x+emifa" }, 348c2ecf20Sopenharmony_ci {} 358c2ecf20Sopenharmony_ci}; 368c2ecf20Sopenharmony_ci 378c2ecf20Sopenharmony_ci/* 388c2ecf20Sopenharmony_ci * Parse device tree for existence of an EMIF (External Memory Interface) 398c2ecf20Sopenharmony_ci * and initialize it if found. 408c2ecf20Sopenharmony_ci */ 418c2ecf20Sopenharmony_cistatic int __init c6x_emifa_init(void) 428c2ecf20Sopenharmony_ci{ 438c2ecf20Sopenharmony_ci struct emifa_regs __iomem *regs; 448c2ecf20Sopenharmony_ci struct device_node *node; 458c2ecf20Sopenharmony_ci const __be32 *p; 468c2ecf20Sopenharmony_ci u32 val; 478c2ecf20Sopenharmony_ci int i, len, err; 488c2ecf20Sopenharmony_ci 498c2ecf20Sopenharmony_ci node = of_find_matching_node(NULL, emifa_match); 508c2ecf20Sopenharmony_ci if (!node) 518c2ecf20Sopenharmony_ci return 0; 528c2ecf20Sopenharmony_ci 538c2ecf20Sopenharmony_ci regs = of_iomap(node, 0); 548c2ecf20Sopenharmony_ci if (!regs) 558c2ecf20Sopenharmony_ci return 0; 568c2ecf20Sopenharmony_ci 578c2ecf20Sopenharmony_ci /* look for a dscr-based enable for emifa pin buffers */ 588c2ecf20Sopenharmony_ci err = of_property_read_u32_array(node, "ti,dscr-dev-enable", &val, 1); 598c2ecf20Sopenharmony_ci if (!err) 608c2ecf20Sopenharmony_ci dscr_set_devstate(val, DSCR_DEVSTATE_ENABLED); 618c2ecf20Sopenharmony_ci 628c2ecf20Sopenharmony_ci /* set up the chip enables */ 638c2ecf20Sopenharmony_ci p = of_get_property(node, "ti,emifa-ce-config", &len); 648c2ecf20Sopenharmony_ci if (p) { 658c2ecf20Sopenharmony_ci len /= sizeof(u32); 668c2ecf20Sopenharmony_ci if (len > NUM_EMIFA_CHIP_ENABLES) 678c2ecf20Sopenharmony_ci len = NUM_EMIFA_CHIP_ENABLES; 688c2ecf20Sopenharmony_ci for (i = 0; i <= len; i++) 698c2ecf20Sopenharmony_ci soc_writel(be32_to_cpup(&p[i]), ®s->cecfg[i]); 708c2ecf20Sopenharmony_ci } 718c2ecf20Sopenharmony_ci 728c2ecf20Sopenharmony_ci err = of_property_read_u32_array(node, "ti,emifa-burst-priority", &val, 1); 738c2ecf20Sopenharmony_ci if (!err) 748c2ecf20Sopenharmony_ci soc_writel(val, ®s->bprio); 758c2ecf20Sopenharmony_ci 768c2ecf20Sopenharmony_ci err = of_property_read_u32_array(node, "ti,emifa-async-wait-control", &val, 1); 778c2ecf20Sopenharmony_ci if (!err) 788c2ecf20Sopenharmony_ci soc_writel(val, ®s->awcc); 798c2ecf20Sopenharmony_ci 808c2ecf20Sopenharmony_ci iounmap(regs); 818c2ecf20Sopenharmony_ci of_node_put(node); 828c2ecf20Sopenharmony_ci return 0; 838c2ecf20Sopenharmony_ci} 848c2ecf20Sopenharmony_cipure_initcall(c6x_emifa_init); 85