1
2
3
4
5
6
7#include <config.h>
8#include <common.h>
9#include <malloc.h>
10#include <i2c.h>
11#include <asm/types.h>
12#include <asm/io.h>
13#include <asm/errno.h>
14#include <asm/arch/clock.h>
15#include <asm/arch/gpio.h>
16#include <asm/arch/hardware.h>
17#include <asm/arch/sys_proto.h>
18#include <asm/arch/prcmu.h>
19#ifdef CONFIG_MMC
20#include "../../../drivers/mmc/arm_pl180_mmci.h"
21#endif
22
23#define NOMADIK_PER4_BASE (0x80150000)
24#define NOMADIK_BACKUPRAM0_BASE (NOMADIK_PER4_BASE + 0x00000)
25#define NOMADIK_BACKUPRAM1_BASE (NOMADIK_PER4_BASE + 0x01000)
26
27
28
29
30
31
32
33
34#define PRCM_ARMCLKFIX_MGT_REG (PRCMU_BASE + 0x000)
35#define PRCM_ACLK_MGT_REG (PRCMU_BASE + 0x004)
36#define PRCM_SVAMMDSPCLK_MGT_REG (PRCMU_BASE + 0x008)
37#define PRCM_SIAMMDSPCLK_MGT_REG (PRCMU_BASE + 0x00C)
38#define PRCM_SAAMMDSPCLK_MGT_REG (PRCMU_BASE + 0x010)
39#define PRCM_SGACLK_MGT_REG (PRCMU_BASE + 0x014)
40#define PRCM_UARTCLK_MGT_REG (PRCMU_BASE + 0x018)
41#define PRCM_MSPCLK_MGT_REG (PRCMU_BASE + 0x01C)
42#define PRCM_I2CCLK_MGT_REG (PRCMU_BASE + 0x020)
43#define PRCM_SDMMCCLK_MGT_REG (PRCMU_BASE + 0x024)
44#define PRCM_SLIMCLK_MGT_REG (PRCMU_BASE + 0x028)
45#define PRCM_PER1CLK_MGT_REG (PRCMU_BASE + 0x02C)
46#define PRCM_PER2CLK_MGT_REG (PRCMU_BASE + 0x030)
47#define PRCM_PER3CLK_MGT_REG (PRCMU_BASE + 0x034)
48#define PRCM_PER5CLK_MGT_REG (PRCMU_BASE + 0x038)
49#define PRCM_PER6CLK_MGT_REG (PRCMU_BASE + 0x03C)
50#define PRCM_PER7CLK_MGT_REG (PRCMU_BASE + 0x040)
51#define PRCM_DMACLK_MGT_REG (PRCMU_BASE + 0x074)
52#define PRCM_B2R2CLK_MGT_REG (PRCMU_BASE + 0x078)
53
54#define PRCM_PLLSOC0_FREQ_REG (PRCMU_BASE + 0x080)
55#define PRCM_PLLSOC1_FREQ_REG (PRCMU_BASE + 0x084)
56#define PRCM_PLLARM_FREQ_REG (PRCMU_BASE + 0x088)
57#define PRCM_PLLDDR_FREQ_REG (PRCMU_BASE + 0x08C)
58#define PRCM_ARM_CHGCLKREQ_REG (PRCMU_BASE + 0x114)
59
60#define PRCM_TCR (PRCMU_BASE + 0x1C8)
61
62
63
64
65#define DMC_BASE_ADDR 0x80156000
66#define DMC_CTL_97 (DMC_BASE_ADDR + 0x184)
67
68int board_id;
69
70
71enum {
72 GATED = 0,
73 PLLSOC0,
74 PLLSOC1,
75 PLLDDR,
76 PLLARM,
77};
78
79static struct pll_freq_regs {
80 int idx;
81 uint32_t addr;
82} pll_freq_regs[] = {
83 {PLLSOC0, PRCM_PLLSOC0_FREQ_REG},
84 {PLLSOC1, PRCM_PLLSOC1_FREQ_REG},
85 {PLLDDR, PRCM_PLLDDR_FREQ_REG},
86 {PLLARM, PRCM_PLLARM_FREQ_REG},
87 {0, 0},
88};
89
90static const char *pll_name[5] = {"GATED", "SOC0", "SOC1", "DDR", "ARM"};
91static uint32_t pll_khz[5];
92
93static struct clk_mgt_regs {
94 uint32_t addr;
95 uint32_t val;
96 const char *descr;
97} clk_mgt_regs[] = {
98
99 {PRCM_ARMCLKFIX_MGT_REG, 0x0120, "ARMCLKFIX"},
100 {PRCM_ACLK_MGT_REG, 0x0125, "ACLK"},
101 {PRCM_SVAMMDSPCLK_MGT_REG, 0x1122, "SVA"},
102 {PRCM_SIAMMDSPCLK_MGT_REG, 0x0022, "SIA"},
103 {PRCM_SAAMMDSPCLK_MGT_REG, 0x0822, "SAA"},
104 {PRCM_SGACLK_MGT_REG, 0x0024, "SGA"},
105 {PRCM_UARTCLK_MGT_REG, 0x0300, "UART"},
106 {PRCM_MSPCLK_MGT_REG, 0x0200, "MSP"},
107 {PRCM_I2CCLK_MGT_REG, 0x0130, "I2C"},
108 {PRCM_SDMMCCLK_MGT_REG, 0x0130, "SDMMC"},
109 {PRCM_PER1CLK_MGT_REG, 0x126, "PER1"},
110 {PRCM_PER2CLK_MGT_REG, 0x126, "PER2"},
111 {PRCM_PER3CLK_MGT_REG, 0x126, "PER3"},
112 {PRCM_PER5CLK_MGT_REG, 0x126, "PER5"},
113 {PRCM_PER6CLK_MGT_REG, 0x126, "PER6"},
114 {PRCM_PER7CLK_MGT_REG, 0x128, "PER7"},
115 {PRCM_DMACLK_MGT_REG, 0x125, "DMA"},
116 {PRCM_B2R2CLK_MGT_REG, 0x025, "B2R2"},
117 {0, 0, NULL},
118};
119
120static void init_regs(void);
121
122DECLARE_GLOBAL_DATA_PTR;
123#if defined(CONFIG_SHOW_BOOT_PROGRESS)
124void show_boot_progress(int progress)
125{
126 printf("Boot reached stage %d\n", progress);
127}
128#endif
129
130
131
132
133
134int board_early_init_f(void)
135{
136 init_regs();
137 return 0;
138}
139
140int board_init(void)
141{
142 uint32_t unused_cols_rows;
143 unsigned int nrows;
144 unsigned int ncols;
145
146 gd->bd->bi_arch_number = 0x1A4;
147 gd->bd->bi_boot_params = 0x00000100;
148 gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE;
149
150
151
152
153
154
155
156
157
158
159
160 unused_cols_rows = readl(DMC_CTL_97);
161 nrows = 15 - (unused_cols_rows & 0x07);
162 ncols = 11 - ((unused_cols_rows & 0x0700) >> 8);
163 gd->bd->bi_dram[0].size = 2 * (1 << (nrows + ncols)) * 8 * 4;
164
165 icache_enable();
166
167 return 0;
168}
169
170int dram_init(void)
171{
172 gd->ram_size = PHYS_SDRAM_SIZE_1;
173
174 return 0;
175}
176
177unsigned int addr_vall_arr[] = {
178 0x8011F000, 0x0000FFFF,
179 0x8011F008, 0x00001CFF,
180 0x8000F000, 0x00007FFF,
181 0x8000F008, 0x00007FFF,
182 0x80157020, 0x00000150,
183 0x8012F000, 0x00007FFF,
184 0x8012F008, 0x00007FFF,
185 0xA03DF000, 0x0000000D,
186 0x8011E00C, 0x00000000,
187 0x8011E004, 0x0000FFE0,
188 0x8011E020, 0x0000FFE0,
189 0x8011E024, 0x00000000,
190 0x8012E000, 0x20000000,
191 0x8012E00C, 0x00000000,
192 0x8012E004, 0x0FFC0000,
193 0x8012E020, 0x60000000,
194 0x8012E024, 0x60000000,
195 0x801571E4, 0x0000000C,
196
197 0x80157024, 0x00000130,
198 0xA03FF000, 0x00000003,
199 0xA03FF008, 0x00000001,
200 0xA03FE00C, 0x00000000,
201 0xA03FE020, 0x00000FFF,
202 0xA03FE024, 0x00000000
203};
204
205#ifdef CONFIG_BOARD_LATE_INIT
206
207
208
209
210int board_late_init(void)
211{
212 uchar byte;
213
214
215
216
217
218
219
220
221
222 (void) i2c_set_bus_num(0);
223 (void) i2c_read(CONFIG_SYS_I2C_GPIOE_ADDR, 0x80, 1, &byte, 1);
224 if (byte == 0x01) {
225 board_id = 0;
226 setenv("board_id", "0");
227 } else {
228 board_id = 1;
229 setenv("board_id", "1");
230 }
231#ifdef CONFIG_MMC
232 u8500_mmc_power_init();
233
234
235
236
237
238 if (board_id == 0) {
239
240 byte = 0x0c;
241 (void) i2c_write(CONFIG_SYS_I2C_GPIOE_ADDR, 0x89, 1, &byte, 1);
242 (void) i2c_write(CONFIG_SYS_I2C_GPIOE_ADDR, 0x83, 1, &byte, 1);
243 } else {
244
245
246 byte = 0x06;
247 (void) i2c_write(CONFIG_SYS_I2C_GPIOE_ADDR, 0xC8, 1, &byte, 1);
248
249 (void) i2c_write(CONFIG_SYS_I2C_GPIOE_ADDR, 0xC4, 1,
250 (uchar []) {0x06, 0x06}, 2);
251 }
252#endif
253
254
255
256
257
258
259 if (gd->bd->bi_dram[0].size == 0x10000000) {
260 setenv("memargs", "setenv bootargs ${bootargs} ${memargs256}");
261 setenv("mem", "256M");
262 } else {
263 setenv("memargs", "setenv bootargs ${bootargs} ${memargs512}");
264 setenv("mem", "512M");
265 }
266
267 return 0;
268}
269#endif
270
271static void early_gpio_setup(struct gpio_register *gpio_reg, u32 bits)
272{
273 writel(readl(&gpio_reg->gpio_dats) | bits, &gpio_reg->gpio_dats);
274 writel(readl(&gpio_reg->gpio_pdis) & ~bits, &gpio_reg->gpio_pdis);
275}
276
277static void init_regs(void)
278{
279
280 struct prcmu *prcmu = (struct prcmu *) U8500_PRCMU_BASE;
281
282
283 writel(1 << 17, &prcmu->tcr);
284
285 u8500_prcmu_enable(&prcmu->per1clk_mgt);
286 u8500_prcmu_enable(&prcmu->per2clk_mgt);
287 u8500_prcmu_enable(&prcmu->per3clk_mgt);
288 u8500_prcmu_enable(&prcmu->per5clk_mgt);
289 u8500_prcmu_enable(&prcmu->per6clk_mgt);
290 u8500_prcmu_enable(&prcmu->per7clk_mgt);
291
292 u8500_prcmu_enable(&prcmu->uartclk_mgt);
293 u8500_prcmu_enable(&prcmu->i2cclk_mgt);
294
295 u8500_prcmu_enable(&prcmu->sdmmcclk_mgt);
296
297 u8500_clock_enable(1, 9, -1);
298
299 u8500_clock_enable(2, 11, -1);
300
301 u8500_clock_enable(3, 8, -1);
302 u8500_clock_enable(5, 1, -1);
303
304 u8500_clock_enable(3, 6, 6);
305
306 gpio_altfuncenable(GPIO_ALT_I2C_0, "I2C0");
307 u8500_clock_enable(3, 3, 3);
308
309 early_gpio_setup((struct gpio_register *)U8500_GPIO_0_BASE, 0x60000000);
310 gpio_altfuncenable(GPIO_ALT_UART_2, "UART2");
311
312 early_gpio_setup((struct gpio_register *)U8500_GPIO_6_BASE, 0x0000ffe0);
313 gpio_altfuncenable(GPIO_ALT_EMMC, "EMMC");
314
315 early_gpio_setup((struct gpio_register *)U8500_GPIO_0_BASE, 0x0000ffe0);
316 gpio_altfuncenable(GPIO_ALT_SD_CARD0, "SDCARD");
317
318 u8500_clock_enable(1, 5, 5);
319 u8500_clock_enable(2, 4, 2);
320
321 u8500_clock_enable(6, 7, -1);
322 u8500_clock_enable(3, 4, 4);
323
324 early_gpio_setup((struct gpio_register *)U8500_GPIO_4_BASE, 0x000007ff);
325 gpio_altfuncenable(GPIO_ALT_POP_EMMC, "EMMC");
326
327
328
329
330
331
332
333
334
335 u8500_clock_enable(1, 1, 1);
336 u8500_clock_enable(1, 0, 0);
337
338 u8500_clock_enable(3, 2, 2);
339 u8500_clock_enable(3, 1, 1);
340
341 u8500_clock_enable(2, 8, -1);
342 u8500_clock_enable(2, 5, 3);
343}
344
345#ifdef CONFIG_MMC
346static int u8500_mmci_board_init(void)
347{
348 enum gpio_error error;
349 struct gpio_register *gpio_base_address;
350
351 gpio_base_address = (void *)(U8500_GPIO_0_BASE);
352 gpio_base_address->gpio_dats |= 0xFFC0000;
353 gpio_base_address->gpio_pdis &= ~0xFFC0000;
354
355
356 error = gpio_altfuncenable(GPIO_ALT_SD_CARD0, "MMC");
357 if (error != GPIO_OK) {
358 printf("u8500_mmci_board_init() gpio_altfuncenable failed\n");
359 return -ENODEV;
360 }
361 return 0;
362}
363
364int board_mmc_init(bd_t *bd)
365{
366 struct pl180_mmc_host *host;
367
368 if (u8500_mmci_board_init())
369 return -ENODEV;
370
371 host = malloc(sizeof(struct pl180_mmc_host));
372 if (!host)
373 return -ENOMEM;
374 memset(host, 0, sizeof(*host));
375
376 strcpy(host->name, "MMC");
377 host->base = (struct sdi_registers *)CONFIG_ARM_PL180_MMCI_BASE;
378 host->pwr_init = INIT_PWR;
379 host->clkdiv_init = SDI_CLKCR_CLKDIV_INIT_V1 | SDI_CLKCR_CLKEN;
380 host->voltages = VOLTAGE_WINDOW_MMC;
381 host->caps = 0;
382 host->clock_in = ARM_MCLK;
383 host->clock_min = ARM_MCLK / (2 * (SDI_CLKCR_CLKDIV_INIT_V1 + 1));
384 host->clock_max = CONFIG_ARM_PL180_MMCI_CLOCK_FREQ;
385
386 return arm_pl180_mmci_init(host);
387}
388#endif
389
390
391
392
393
394static uint32_t get_pll_freq_khz(uint32_t inclk_khz, uint32_t freq_reg)
395{
396 uint32_t idf, ldf, odf, seldiv, phi;
397
398
399
400
401
402
403
404
405
406
407 idf = (freq_reg & 0x70000) >> 16;
408 ldf = (freq_reg & 0xff) * 2;
409 odf = (freq_reg & 0x3f00) >> 8;
410 seldiv = (freq_reg & 0x01000000) >> 24;
411 phi = (inclk_khz * ldf) / (2 * odf * idf);
412 if (seldiv)
413 phi = phi/2;
414
415 return phi;
416}
417
418int do_clkinfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
419{
420 uint32_t inclk_khz;
421 uint32_t reg, phi;
422 uint32_t clk_khz;
423 unsigned int clk_sel;
424 struct clk_mgt_regs *clks = clk_mgt_regs;
425 struct pll_freq_regs *plls = pll_freq_regs;
426
427
428
429
430
431 inclk_khz = 38400;
432 while (plls->addr) {
433 reg = readl(plls->addr);
434 phi = get_pll_freq_khz(inclk_khz, reg);
435 pll_khz[plls->idx] = phi;
436 printf("%s PLL out frequency: %d.%d Mhz\n",
437 pll_name[plls->idx], phi/1000, phi % 1000);
438 plls++;
439 }
440
441
442 reg = readl(PRCM_ARM_CHGCLKREQ_REG);
443 printf("A9 running on %s\n",
444 (reg & 1) ? "external clock" : "ARM PLL");
445
446
447 printf("\n%19s %9s %7s %9s enabled\n",
448 "name(addr)", "value", "PLL", "CLK[MHz]");
449 while (clks->addr) {
450 reg = readl(clks->addr);
451
452
453 clk_sel = ffs((reg >> 5) & 0x7);
454
455 if (reg & 0x200)
456 clk_khz = 38400;
457 else if ((reg & 0x1f) == 0)
458
459 clk_khz = 0;
460 else
461 clk_khz = pll_khz[clk_sel] / (reg & 0x1f);
462
463 printf("%9s(%08x): %08x, %6s, %4d.%03d, %s\n",
464 clks->descr, clks->addr, reg, pll_name[clk_sel],
465 clk_khz / 1000, clk_khz % 1000,
466 (reg & 0x100) ? "ena" : "dis");
467 clks++;
468 }
469
470 return 0;
471}
472
473U_BOOT_CMD(
474 clkinfo, 1, 1, do_clkinfo,
475 "print clock info",
476 ""
477);
478