/* * EMIF driver * * Copyright (C) 2012 Texas Instruments, Inc. * * Aneesh V <aneesh@ti.com> * Santosh Shilimkar <santosh.shilimkar@ti.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/kernel.h>#include<linux/reboot.h>#include<linux/platform_data/emif_plat.h>#include<linux/io.h>#include<linux/device.h>#include<linux/platform_device.h>#include<linux/interrupt.h>#include<linux/slab.h>#include<linux/seq_file.h>#include<linux/module.h>#include<linux/list.h>#include<linux/spinlock.h>#include<memory/jedec_ddr.h>#include"emif.h"/** * struct emif_data - Per device static data for driver's use * @duplicate: Whether the DDR devices attached to this EMIF * instance are exactly same as that on EMIF1. In * this case we can save some memory and processing * @temperature_level: Maximum temperature of LPDDR2 devices attached * to this EMIF - read from MR4 register. If there * are two devices attached to this EMIF, this * value is the maximum of the two temperature * levels. * @node: node in the device list * @base: base address of memory-mapped IO registers. * @dev: device pointer. * @addressing table with addressing information from the spec * @regs_cache: An array of 'struct emif_regs' that stores * calculated register values for different * frequencies, to avoid re-calculating them on * each DVFS transition. * @curr_regs: The set of register values used in the last * frequency change (i.e. corresponding to the * frequency in effect at the moment) * @plat_data: Pointer to saved platform data. */structemif_data{u8duplicate;u8temperature_level;u8lpmode;structlist_headnode;unsignedlongirq_state;void__iomem*base;structdevice*dev;conststructlpddr2_addressing*addressing;structemif_regs*regs_cache[EMIF_MAX_NUM_FREQUENCIES];structemif_regs*curr_regs;structemif_platform_data*plat_data;};staticstructemif_data*emif1;staticspinlock_temif_lock;staticunsignedlongirq_state;staticu32t_ck;/* DDR clock period in ps */staticLIST_HEAD(device_list);/* * Calculate the period of DDR clock from frequency value */staticvoidset_ddr_clk_period(u32freq){/* Divide 10^12 by frequency to get period in ps */t_ck=(u32)DIV_ROUND_UP_ULL(1000000000000ull,freq);}/* * Get the CL from SDRAM_CONFIG register */staticu32get_cl(structemif_data*emif){u32cl;void__iomem*base