1 /*
2  * Copyright (C) 2011 Google, Inc.
3  *
4  * Author:
5  *	Colin Cross <ccross@android.com>
6  *
7  * This software is licensed under the terms of the GNU General Public
8  * License version 2, as published by the Free Software Foundation, and
9  * may be copied, distributed, and modified under those terms.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  */
17 
18 #include <linux/kernel.h>
19 #include <linux/clk.h>
20 #include <linux/err.h>
21 #include <linux/io.h>
22 #include <linux/module.h>
23 
24 #include <mach/iomap.h>
25 
26 #include "tegra2_emc.h"
27 
28 #ifdef CONFIG_TEGRA_EMC_SCALING_ENABLE
29 static bool emc_enable = true;
30 #else
31 static bool emc_enable;
32 #endif
33 module_param(emc_enable, bool, 0644);
34 
35 static void __iomem *emc = IO_ADDRESS(TEGRA_EMC_BASE);
36 static const struct tegra_emc_table *tegra_emc_table;
37 static int tegra_emc_table_size;
38 
emc_writel(u32 val,unsigned long addr)39 static inline void emc_writel(u32 val, unsigned long addr)
40 {
41 	writel(val, emc + addr);
42 }
43 
emc_readl(unsigned long addr)44 static inline u32 emc_readl(unsigned long addr)
45 {
46 	return readl(emc + addr);
47 }
48 
49 static const unsigned long emc_reg_addr[TEGRA_EMC_NUM_REGS] = {
50 	0x2c,	/* RC */
51 	0x30,	/* RFC */
52 	0x34,	/* RAS */
53 	0x38,	/* RP */
54 	0x3c,	/* R2W */
55 	0x40,	/* W2R */
56 	0x44,	/* R2P */
57 	0x48,	/* W2P */
58 	0x4c,	/* RD_RCD */
59 	0x50,	/* WR_RCD */
60 	0x54,	/* RRD */
61 	0x58,	/* REXT */
62 	0x5c,	/* WDV */
63 	0x60,	/* QUSE */
64 	0x64,	/* QRST */
65 	0x68,	/* QSAFE */
66 	0x6c,	/* RDV */
67 	0x70,	/* REFRESH */
68 	0x74,	/* BURST_REFRESH_NUM */
69 	0x78,	/* PDEX2WR */
70 	0x7c,	/* PDEX2RD */
71 	0x80,	/* PCHG2PDEN */
72 	0x84,	/* ACT2PDEN */
73 	0x88,	/* AR2PDEN */
74 	0x8c,	/* RW2PDEN */
75 	0x90,	/* TXSR */
76 	0x94,	/* TCKE */
77 	0x98,	/* TFAW */
78 	0x9c,	/* TRPAB */
79 	0xa0,	/* TCLKSTABLE */
80 	0xa4,	/* TCLKSTOP */
81 	0xa8,	/* TREFBW */
82 	0xac,	/* QUSE_EXTRA */
83 	0x114,	/* FBIO_CFG6 */
84 	0xb0,	/* ODT_WRITE */
85 	0xb4,	/* ODT_READ */
86 	0x104,	/* FBIO_CFG5 */
87 	0x2bc,	/* CFG_DIG_DLL */
88 	0x2c0,	/* DLL_XFORM_DQS */
89 	0x2c4,	/* DLL_XFORM_QUSE */
90 	0x2e0,	/* ZCAL_REF_CNT */
91 	0x2e4,	/* ZCAL_WAIT_CNT */
92 	0x2a8,	/* AUTO_CAL_INTERVAL */
93 	0x2d0,	/* CFG_CLKTRIM_0 */
94 	0x2d4,	/* CFG_CLKTRIM_1 */
95 	0x2d8,	/* CFG_CLKTRIM_2 */
96 };
97 
98 /* Select the closest EMC rate that is higher than the requested rate */
tegra_emc_round_rate(unsigned long rate)99 long tegra_emc_round_rate(unsigned long rate)
100 {
101 	int i;
102 	int best = -1;
103 	unsigned long distance = ULONG_MAX;
104 
105 	if (!tegra_emc_table)
106 		return -EINVAL;
107 
108 	if (!emc_enable)
109 		return -EINVAL;
110 
111 	pr_debug("%s: %lu\n", __func__, rate);
112 
113 	/*
114 	 * The EMC clock rate is twice the bus rate, and the bus rate is
115 	 * measured in kHz
116 	 */
117 	rate = rate / 2 / 1000;
118 
119 	for (i = 0; i < tegra_emc_table_size; i++) {
120 		if (tegra_emc_table[i].rate >= rate &&
121 		    (tegra_emc_table[i].rate - rate) < distance) {
122 			distance = tegra_emc_table[i].rate - rate;
123 			best = i;
124 		}
125 	}
126 
127 	if (best < 0)
128 		return -EINVAL;
129 
130 	pr_debug("%s: using %lu\n", __func__, tegra_emc_table[best].rate);
131 
132 	return tegra_emc_table[best].rate * 2 * 1000;
133 }
134 
135 /*
136  * The EMC registers have shadow registers.  When the EMC clock is updated
137  * in the clock controller, the shadow registers are copied to the active
138  * registers, allowing glitchless memory bus frequency changes.
139  * This function updates the shadow registers for a new clock frequency,
140  * and relies on the clock lock on the emc clock to avoid races between
141  * multiple frequency changes
142  */
tegra_emc_set_rate(unsigned long rate)143 int tegra_emc_set_rate(unsigned long rate)
144 {
145 	int i;
146 	int j;
147 
148 	if (!tegra_emc_table)
149 		return -EINVAL;
150 
151 	/*
152 	 * The EMC clock rate is twice the bus rate, and the bus rate is
153 	 * measured in kHz
154 	 */
155 	rate = rate / 2 / 1000;
156 
157 	for (i = 0; i < tegra_emc_table_size; i++)
158 		if (tegra_emc_table[i].rate == rate)
159 			break;
160 
161 	if (i >= tegra_emc_table_size)
162 		return -EINVAL;
163 
164 	pr_debug("%s: setting to %lu\n", __func__, rate);
165 
166 	for (j = 0; j < TEGRA_EMC_NUM_REGS; j++)
167 		emc_writel(tegra_emc_table[i].regs[j], emc_reg_addr[j]);
168 
169 	emc_readl(tegra_emc_table[i].regs[TEGRA_EMC_NUM_REGS - 1]);
170 
171 	return 0;
172 }
173 
tegra_init_emc(const struct tegra_emc_table * table,int table_size)174 void tegra_init_emc(const struct tegra_emc_table *table, int table_size)
175 {
176 	tegra_emc_table = table;
177 	tegra_emc_table_size = table_size;
178 }
179