1
|
/*
|
2
|
* som.c
|
3
|
*
|
4
|
* Copyright (C) 2012 Critical Link LLC - http://www.criticallink.com/
|
5
|
* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
|
6
|
*
|
7
|
* This program is free software; you can redistribute it and/or
|
8
|
* modify it under the terms of the GNU General Public License as
|
9
|
* published by the Free Software Foundation version 2.
|
10
|
*
|
11
|
* This program is distributed "as is" WITHOUT ANY WARRANTY of any
|
12
|
* kind, whether express or implied; without even the implied warranty
|
13
|
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
14
|
* GNU General Public License for more details.
|
15
|
*/
|
16
|
|
17
|
#include <common.h>
|
18
|
#include <asm/cache.h>
|
19
|
#include <asm/omap_common.h>
|
20
|
#include <asm/io.h>
|
21
|
#include <asm/arch/cpu.h>
|
22
|
#include <asm/arch/ddr_defs.h>
|
23
|
#include <asm/arch/hardware.h>
|
24
|
#include <asm/arch/mmc_host_def.h>
|
25
|
#include <asm/arch/sys_proto.h>
|
26
|
#include <asm/arch/mem.h>
|
27
|
#include <asm/arch/nand.h>
|
28
|
#include <asm/arch/clock.h>
|
29
|
#include <linux/mtd/nand.h>
|
30
|
#include <nand.h>
|
31
|
#include <net.h>
|
32
|
#include <miiphy.h>
|
33
|
#include <netdev.h>
|
34
|
#include <spi_flash.h>
|
35
|
#include "common_def.h"
|
36
|
#include "pmic.h"
|
37
|
#include "tps65217.h"
|
38
|
#include <i2c.h>
|
39
|
#include <serial.h>
|
40
|
#include "config_block.h"
|
41
|
|
42
|
DECLARE_GLOBAL_DATA_PTR;
|
43
|
|
44
|
/* Profile 0 is the dev kit board, profile 1 is the test fixture */
|
45
|
#ifdef CONFIG_AM335X_TF
|
46
|
static unsigned char profile = PROFILE_1;
|
47
|
#else
|
48
|
static unsigned char profile = PROFILE_0;
|
49
|
#endif
|
50
|
|
51
|
/* UART Defines */
|
52
|
#define UART_SYSCFG_OFFSET (0x54)
|
53
|
#define UART_SYSSTS_OFFSET (0x58)
|
54
|
|
55
|
#define UART_RESET (0x1 << 1)
|
56
|
#define UART_CLK_RUNNING_MASK 0x1
|
57
|
#define UART_SMART_IDLE_EN (0x1 << 0x3)
|
58
|
|
59
|
/* Timer Defines */
|
60
|
#define TSICR_REG 0x54
|
61
|
#define TIOCP_CFG_REG 0x10
|
62
|
#define TCLR_REG 0x38
|
63
|
|
64
|
/*
|
65
|
* I2C Address of various board
|
66
|
*/
|
67
|
#define I2C_EEPROM_ADDR 0x50
|
68
|
#define I2C_EEPROM_BUS 1
|
69
|
#define I2C_PMIC_CTL_BUS 2
|
70
|
#define I2C_PMIC_SMT_BUS 1
|
71
|
|
72
|
/* RGMII mode define */
|
73
|
#define RGMII_MODE_ENABLE 0xA
|
74
|
#define RMII_MODE_ENABLE 0x5
|
75
|
#define MII_MODE_ENABLE 0x0
|
76
|
|
77
|
/* TLK110 PHY registers */
|
78
|
#define TLK110_COARSEGAIN_REG 0x00A3
|
79
|
#define TLK110_LPFHPF_REG 0x00AC
|
80
|
#define TLK110_SPAREANALOG_REG 0x00B9
|
81
|
#define TLK110_VRCR_REG 0x00D0
|
82
|
#define TLK110_SETFFE_REG (unsigned char)0x0107
|
83
|
#define TLK110_FTSP_REG (unsigned char)0x0154
|
84
|
#define TLK110_ALFATPIDL_REG 0x002A
|
85
|
#define TLK110_PSCOEF21_REG 0x0096
|
86
|
#define TLK110_PSCOEF3_REG 0x0097
|
87
|
#define TLK110_ALFAFACTOR1_REG 0x002C
|
88
|
#define TLK110_ALFAFACTOR2_REG 0x0023
|
89
|
#define TLK110_CFGPS_REG 0x0095
|
90
|
#define TLK110_FTSPTXGAIN_REG (unsigned char)0x0150
|
91
|
#define TLK110_SWSCR3_REG 0x000B
|
92
|
#define TLK110_SCFALLBACK_REG 0x0040
|
93
|
#define TLK110_PHYRCR_REG 0x001F
|
94
|
|
95
|
/* TLK110 register writes values */
|
96
|
#define TLK110_COARSEGAIN_VAL 0x0000
|
97
|
#define TLK110_LPFHPF_VAL 0x8000
|
98
|
#define TLK110_SPAREANALOG_VAL 0x0000
|
99
|
#define TLK110_VRCR_VAL 0x0008
|
100
|
#define TLK110_SETFFE_VAL 0x0605
|
101
|
#define TLK110_FTSP_VAL 0x0255
|
102
|
#define TLK110_ALFATPIDL_VAL 0x7998
|
103
|
#define TLK110_PSCOEF21_VAL 0x3A20
|
104
|
#define TLK110_PSCOEF3_VAL 0x003F
|
105
|
#define TLK110_ALFAFACTOR1_VAL 0xFF80
|
106
|
#define TLK110_ALFAFACTOR2_VAL 0x021C
|
107
|
#define TLK110_CFGPS_VAL 0x0000
|
108
|
#define TLK110_FTSPTXGAIN_VAL 0x6A88
|
109
|
#define TLK110_SWSCR3_VAL 0x0000
|
110
|
#define TLK110_SCFALLBACK_VAL 0xC11D
|
111
|
#define TLK110_PHYRCR_VAL 0x4000
|
112
|
#define TLK110_PHYIDR1 0x2000
|
113
|
#define TLK110_PHYIDR2 0xA201
|
114
|
|
115
|
#define NO_OF_MAC_ADDR 3
|
116
|
#define ETH_ALEN 6
|
117
|
|
118
|
|
119
|
|
120
|
/* set the D3 LED to on of off. This LED is hooked up to the GPIO0
|
121
|
* output of the PMIC.
|
122
|
* \param[in] b if non-zero, turn LED on, else off
|
123
|
*/
|
124
|
inline void set_led_d3(int b) {
|
125
|
unsigned char v;
|
126
|
// save the bus number
|
127
|
int bus = i2c_get_bus_num();
|
128
|
i2c_set_bus_num(I2C_PMIC_CTL_BUS);
|
129
|
i2c_read(PMIC_CTRL_I2C_ADDR, PMIC_GPIO0_REG, 1, &v, 1);
|
130
|
if(b)
|
131
|
v |= 1;
|
132
|
else
|
133
|
v &= 0xfe;
|
134
|
i2c_write(PMIC_CTRL_I2C_ADDR, PMIC_GPIO0_REG, 1, &v, 1);
|
135
|
// put it back
|
136
|
i2c_set_bus_num(bus);
|
137
|
}
|
138
|
|
139
|
/*
|
140
|
* dram_init:
|
141
|
* At this point we have initialized the i2c bus and can read the
|
142
|
* EEPROM which will tell us what board and revision we are on.
|
143
|
*/
|
144
|
int dram_init(void)
|
145
|
{
|
146
|
gd->ram_size = PHYS_DRAM_1_SIZE;
|
147
|
|
148
|
return 0;
|
149
|
}
|
150
|
|
151
|
void dram_init_banksize (void)
|
152
|
{
|
153
|
/* Fill up board info */
|
154
|
gd->bd->bi_dram[0].start = PHYS_DRAM_1;
|
155
|
gd->bd->bi_dram[0].size = PHYS_DRAM_1_SIZE;
|
156
|
}
|
157
|
|
158
|
#ifdef CONFIG_SPL_BUILD
|
159
|
static void Data_Macro_Config(int dataMacroNum)
|
160
|
{
|
161
|
u32 BaseAddrOffset = 0x00;;
|
162
|
|
163
|
if (dataMacroNum == 1)
|
164
|
BaseAddrOffset = 0xA4;
|
165
|
|
166
|
__raw_writel(((DDR2_RD_DQS<<30)|(DDR2_RD_DQS<<20)
|
167
|
|(DDR2_RD_DQS<<10)|(DDR2_RD_DQS<<0)),
|
168
|
(DATA0_RD_DQS_SLAVE_RATIO_0 + BaseAddrOffset));
|
169
|
__raw_writel(DDR2_RD_DQS>>2,
|
170
|
(DATA0_RD_DQS_SLAVE_RATIO_1 + BaseAddrOffset));
|
171
|
__raw_writel(((DDR2_WR_DQS<<30)|(DDR2_WR_DQS<<20)
|
172
|
|(DDR2_WR_DQS<<10)|(DDR2_WR_DQS<<0)),
|
173
|
(DATA0_WR_DQS_SLAVE_RATIO_0 + BaseAddrOffset));
|
174
|
__raw_writel(DDR2_WR_DQS>>2,
|
175
|
(DATA0_WR_DQS_SLAVE_RATIO_1 + BaseAddrOffset));
|
176
|
__raw_writel(((DDR2_PHY_WRLVL<<30)|(DDR2_PHY_WRLVL<<20)
|
177
|
|(DDR2_PHY_WRLVL<<10)|(DDR2_PHY_WRLVL<<0)),
|
178
|
(DATA0_WRLVL_INIT_RATIO_0 + BaseAddrOffset));
|
179
|
__raw_writel(DDR2_PHY_WRLVL>>2,
|
180
|
(DATA0_WRLVL_INIT_RATIO_1 + BaseAddrOffset));
|
181
|
__raw_writel(((DDR2_PHY_GATELVL<<30)|(DDR2_PHY_GATELVL<<20)
|
182
|
|(DDR2_PHY_GATELVL<<10)|(DDR2_PHY_GATELVL<<0)),
|
183
|
(DATA0_GATELVL_INIT_RATIO_0 + BaseAddrOffset));
|
184
|
__raw_writel(DDR2_PHY_GATELVL>>2,
|
185
|
(DATA0_GATELVL_INIT_RATIO_1 + BaseAddrOffset));
|
186
|
__raw_writel(((DDR2_PHY_FIFO_WE<<30)|(DDR2_PHY_FIFO_WE<<20)
|
187
|
|(DDR2_PHY_FIFO_WE<<10)|(DDR2_PHY_FIFO_WE<<0)),
|
188
|
(DATA0_FIFO_WE_SLAVE_RATIO_0 + BaseAddrOffset));
|
189
|
__raw_writel(DDR2_PHY_FIFO_WE>>2,
|
190
|
(DATA0_FIFO_WE_SLAVE_RATIO_1 + BaseAddrOffset));
|
191
|
__raw_writel(((DDR2_PHY_WR_DATA<<30)|(DDR2_PHY_WR_DATA<<20)
|
192
|
|(DDR2_PHY_WR_DATA<<10)|(DDR2_PHY_WR_DATA<<0)),
|
193
|
(DATA0_WR_DATA_SLAVE_RATIO_0 + BaseAddrOffset));
|
194
|
__raw_writel(DDR2_PHY_WR_DATA>>2,
|
195
|
(DATA0_WR_DATA_SLAVE_RATIO_1 + BaseAddrOffset));
|
196
|
__raw_writel(PHY_DLL_LOCK_DIFF,
|
197
|
(DATA0_DLL_LOCK_DIFF_0 + BaseAddrOffset));
|
198
|
}
|
199
|
|
200
|
static void Cmd_Macro_Config(void)
|
201
|
{
|
202
|
__raw_writel(DDR2_RATIO, CMD0_CTRL_SLAVE_RATIO_0);
|
203
|
__raw_writel(CMD_FORCE, CMD0_CTRL_SLAVE_FORCE_0);
|
204
|
__raw_writel(CMD_DELAY, CMD0_CTRL_SLAVE_DELAY_0);
|
205
|
__raw_writel(DDR2_DLL_LOCK_DIFF, CMD0_DLL_LOCK_DIFF_0);
|
206
|
__raw_writel(DDR2_INVERT_CLKOUT, CMD0_INVERT_CLKOUT_0);
|
207
|
|
208
|
__raw_writel(DDR2_RATIO, CMD1_CTRL_SLAVE_RATIO_0);
|
209
|
__raw_writel(CMD_FORCE, CMD1_CTRL_SLAVE_FORCE_0);
|
210
|
__raw_writel(CMD_DELAY, CMD1_CTRL_SLAVE_DELAY_0);
|
211
|
__raw_writel(DDR2_DLL_LOCK_DIFF, CMD1_DLL_LOCK_DIFF_0);
|
212
|
__raw_writel(DDR2_INVERT_CLKOUT, CMD1_INVERT_CLKOUT_0);
|
213
|
|
214
|
__raw_writel(DDR2_RATIO, CMD2_CTRL_SLAVE_RATIO_0);
|
215
|
__raw_writel(CMD_FORCE, CMD2_CTRL_SLAVE_FORCE_0);
|
216
|
__raw_writel(CMD_DELAY, CMD2_CTRL_SLAVE_DELAY_0);
|
217
|
__raw_writel(DDR2_DLL_LOCK_DIFF, CMD2_DLL_LOCK_DIFF_0);
|
218
|
__raw_writel(DDR2_INVERT_CLKOUT, CMD2_INVERT_CLKOUT_0);
|
219
|
}
|
220
|
|
221
|
static void config_vtp(void)
|
222
|
{
|
223
|
__raw_writel(__raw_readl(VTP0_CTRL_REG) | VTP_CTRL_ENABLE,
|
224
|
VTP0_CTRL_REG);
|
225
|
__raw_writel(__raw_readl(VTP0_CTRL_REG) & (~VTP_CTRL_START_EN),
|
226
|
VTP0_CTRL_REG);
|
227
|
__raw_writel(__raw_readl(VTP0_CTRL_REG) | VTP_CTRL_START_EN,
|
228
|
VTP0_CTRL_REG);
|
229
|
|
230
|
/* Poll for READY */
|
231
|
while ((__raw_readl(VTP0_CTRL_REG) & VTP_CTRL_READY) != VTP_CTRL_READY);
|
232
|
}
|
233
|
|
234
|
static void config_emif_ddr2(void)
|
235
|
{
|
236
|
u32 i;
|
237
|
|
238
|
/*Program EMIF0 CFG Registers*/
|
239
|
__raw_writel(EMIF_READ_LATENCY, EMIF4_0_DDR_PHY_CTRL_1);
|
240
|
__raw_writel(EMIF_READ_LATENCY, EMIF4_0_DDR_PHY_CTRL_1_SHADOW);
|
241
|
__raw_writel(EMIF_READ_LATENCY, EMIF4_0_DDR_PHY_CTRL_2);
|
242
|
__raw_writel(EMIF_TIM1, EMIF4_0_SDRAM_TIM_1);
|
243
|
__raw_writel(EMIF_TIM1, EMIF4_0_SDRAM_TIM_1_SHADOW);
|
244
|
__raw_writel(EMIF_TIM2, EMIF4_0_SDRAM_TIM_2);
|
245
|
__raw_writel(EMIF_TIM2, EMIF4_0_SDRAM_TIM_2_SHADOW);
|
246
|
__raw_writel(EMIF_TIM3, EMIF4_0_SDRAM_TIM_3);
|
247
|
__raw_writel(EMIF_TIM3, EMIF4_0_SDRAM_TIM_3_SHADOW);
|
248
|
|
249
|
__raw_writel(EMIF_SDCFG, EMIF4_0_SDRAM_CONFIG);
|
250
|
__raw_writel(EMIF_SDCFG, EMIF4_0_SDRAM_CONFIG2);
|
251
|
|
252
|
/* __raw_writel(EMIF_SDMGT, EMIF0_0_SDRAM_MGMT_CTRL);
|
253
|
__raw_writel(EMIF_SDMGT, EMIF0_0_SDRAM_MGMT_CTRL_SHD); */
|
254
|
__raw_writel(0x00004650, EMIF4_0_SDRAM_REF_CTRL);
|
255
|
__raw_writel(0x00004650, EMIF4_0_SDRAM_REF_CTRL_SHADOW);
|
256
|
|
257
|
for (i = 0; i < 5000; i++) {
|
258
|
|
259
|
}
|
260
|
|
261
|
/* __raw_writel(EMIF_SDMGT, EMIF0_0_SDRAM_MGMT_CTRL);
|
262
|
__raw_writel(EMIF_SDMGT, EMIF0_0_SDRAM_MGMT_CTRL_SHD); */
|
263
|
__raw_writel(EMIF_SDREF, EMIF4_0_SDRAM_REF_CTRL);
|
264
|
__raw_writel(EMIF_SDREF, EMIF4_0_SDRAM_REF_CTRL_SHADOW);
|
265
|
|
266
|
__raw_writel(EMIF_SDCFG, EMIF4_0_SDRAM_CONFIG);
|
267
|
__raw_writel(EMIF_SDCFG, EMIF4_0_SDRAM_CONFIG2);
|
268
|
}
|
269
|
|
270
|
/* void DDR2_EMIF_Config(void); */
|
271
|
|
272
|
/**
|
273
|
* MityARM335X uses the Micron Mt47H128M16RT-25E
|
274
|
* 16M x 16 x 8 bank [128M x 16 = 256MB] DDR2 RAM
|
275
|
* This part has:
|
276
|
* 14 Addr lines A[13:0]
|
277
|
* 3 bank address lines BA[2:0]
|
278
|
* 10 Column address lines A[9:0]
|
279
|
* CaS Latency = 5
|
280
|
*/
|
281
|
static void config_am335x_ddr(void)
|
282
|
{
|
283
|
int data_macro_0 = 0;
|
284
|
int data_macro_1 = 1;
|
285
|
|
286
|
enable_ddr_clocks();
|
287
|
|
288
|
config_vtp();
|
289
|
|
290
|
Cmd_Macro_Config();
|
291
|
|
292
|
Data_Macro_Config(data_macro_0);
|
293
|
Data_Macro_Config(data_macro_1);
|
294
|
|
295
|
__raw_writel(PHY_RANK0_DELAY, DATA0_RANK0_DELAYS_0);
|
296
|
__raw_writel(PHY_RANK0_DELAY, DATA1_RANK0_DELAYS_0);
|
297
|
|
298
|
__raw_writel(DDR_IOCTRL_VALUE, DDR_CMD0_IOCTRL);
|
299
|
__raw_writel(DDR_IOCTRL_VALUE, DDR_CMD1_IOCTRL);
|
300
|
__raw_writel(DDR_IOCTRL_VALUE, DDR_CMD2_IOCTRL);
|
301
|
__raw_writel(DDR_IOCTRL_VALUE, DDR_DATA0_IOCTRL);
|
302
|
__raw_writel(DDR_IOCTRL_VALUE, DDR_DATA1_IOCTRL);
|
303
|
|
304
|
__raw_writel(__raw_readl(DDR_IO_CTRL) & 0xefffffff, DDR_IO_CTRL);
|
305
|
__raw_writel(__raw_readl(DDR_CKE_CTRL) | 0x00000001, DDR_CKE_CTRL);
|
306
|
|
307
|
config_emif_ddr2();
|
308
|
}
|
309
|
|
310
|
static void init_timer(void)
|
311
|
{
|
312
|
/* Reset the Timer */
|
313
|
__raw_writel(0x2, (DM_TIMER2_BASE + TSICR_REG));
|
314
|
|
315
|
/* Wait until the reset is done */
|
316
|
while (__raw_readl(DM_TIMER2_BASE + TIOCP_CFG_REG) & 1);
|
317
|
|
318
|
/* Start the Timer */
|
319
|
__raw_writel(0x1, (DM_TIMER2_BASE + TCLR_REG));
|
320
|
}
|
321
|
|
322
|
#endif // CONFIG_SPL_BUILD
|
323
|
|
324
|
|
325
|
/*
|
326
|
* Read header information from EEPROM into global structure.
|
327
|
*/
|
328
|
int read_eeprom(void)
|
329
|
{
|
330
|
|
331
|
/* Check if baseboard eeprom is available */
|
332
|
i2c_set_bus_num(I2C_EEPROM_BUS);
|
333
|
if (i2c_probe(I2C_EEPROM_ADDR)) {
|
334
|
printf("Could not probe the EEPROM; something fundamentally "
|
335
|
"wrong on the I2C bus.\n");
|
336
|
return 1;
|
337
|
}
|
338
|
|
339
|
|
340
|
// set the profile here based on the factory_config_block
|
341
|
/* try and read our configuration block */
|
342
|
if(0 == get_factory_config_block()) {
|
343
|
// set the profile here based on the factory_config_block
|
344
|
factory_config_block.PartNumber[31] = '\0'; // just to be safe
|
345
|
return 0;
|
346
|
}
|
347
|
else
|
348
|
{
|
349
|
printf("Error reading factory config block\n");
|
350
|
return -1;
|
351
|
}
|
352
|
|
353
|
printf("MityARM335x profile %d - Model No: %32s Serial No: %d\n", profile,
|
354
|
factory_config_block.PartNumber, factory_config_block.SerialNumber);
|
355
|
|
356
|
#ifdef CONFIG_HAVE_CL_CONFIG
|
357
|
if(0 == get_config_block()) {
|
358
|
if(0 != config_block.UBootLocation[0])
|
359
|
{
|
360
|
config_block.UBootLocation[63] = '\0';
|
361
|
/* printf("U-Boot location = %s\n",config_block.UBootLocation ); */
|
362
|
}
|
363
|
else
|
364
|
{
|
365
|
/* printf("U-Boot located in SPI flash"); */
|
366
|
}
|
367
|
}
|
368
|
#endif /* CONFIG_HAVE_CL_CONFIG */
|
369
|
}
|
370
|
|
371
|
#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_BOARD_INIT)
|
372
|
|
373
|
/*
|
374
|
* voltage switching for MPU frequency switching.
|
375
|
* @module = mpu - 0, core - 1
|
376
|
* @vddx_op_vol_sel = vdd voltage to set
|
377
|
*/
|
378
|
|
379
|
#define MPU 0
|
380
|
#define CORE 1
|
381
|
|
382
|
int voltage_update(unsigned int module, unsigned char vddx_op_vol_sel)
|
383
|
{
|
384
|
uchar buf[4];
|
385
|
unsigned int reg_offset;
|
386
|
|
387
|
i2c_set_bus_num(I2C_PMIC_CTL_BUS);
|
388
|
if(module == MPU)
|
389
|
reg_offset = PMIC_VDD1_OP_REG;
|
390
|
else
|
391
|
reg_offset = PMIC_VDD2_OP_REG;
|
392
|
|
393
|
/* Select VDDx OP */
|
394
|
if (i2c_read(PMIC_CTRL_I2C_ADDR, reg_offset, 1, buf, 1))
|
395
|
return 1;
|
396
|
|
397
|
buf[0] &= ~PMIC_OP_REG_CMD_MASK;
|
398
|
|
399
|
if (i2c_write(PMIC_CTRL_I2C_ADDR, reg_offset, 1, buf, 1))
|
400
|
return 1;
|
401
|
|
402
|
/* Configure VDDx OP Voltage */
|
403
|
if (i2c_read(PMIC_CTRL_I2C_ADDR, reg_offset, 1, buf, 1))
|
404
|
return 1;
|
405
|
|
406
|
buf[0] &= ~PMIC_OP_REG_SEL_MASK;
|
407
|
buf[0] |= vddx_op_vol_sel;
|
408
|
|
409
|
if (i2c_write(PMIC_CTRL_I2C_ADDR, reg_offset, 1, buf, 1))
|
410
|
return 1;
|
411
|
|
412
|
if (i2c_read(PMIC_CTRL_I2C_ADDR, reg_offset, 1, buf, 1))
|
413
|
return 1;
|
414
|
|
415
|
if ((buf[0] & PMIC_OP_REG_SEL_MASK ) != vddx_op_vol_sel)
|
416
|
return 1;
|
417
|
|
418
|
return 0;
|
419
|
}
|
420
|
|
421
|
|
422
|
void spl_board_init(void)
|
423
|
{
|
424
|
int ii = 0;
|
425
|
uchar buf[4];
|
426
|
|
427
|
/* Configure the i2c1 and 2 pin mux */
|
428
|
enable_i2c1_pin_mux();
|
429
|
enable_i2c2_pin_mux();
|
430
|
#ifdef CONFIG_SPL_ENET_SUPPORT_NOT
|
431
|
mem_malloc_init(0x82000000, 0x00100000);
|
432
|
set_default_env(NULL);
|
433
|
#endif
|
434
|
|
435
|
#ifdef CONFIG_SPL_MMC_SUPPORT
|
436
|
enable_mmc0_pin_mux();
|
437
|
#endif
|
438
|
printf("\n Sandia Pin Configuration is setting up \n");
|
439
|
enable_sandia_pin_mux();
|
440
|
configure_evm_pin_mux(profile);
|
441
|
printf(" Sandia Pin config is complete.... \n");
|
442
|
|
443
|
i2c_set_bus_num(I2C_PMIC_CTL_BUS); /* calls i2c_init... */
|
444
|
|
445
|
|
446
|
printf("Critical Link AM335X %s\n",(PROFILE_1 == profile)?"Test Fixture":"Dev Kit");
|
447
|
/*
|
448
|
* EVM PMIC code. All boards currently want an MPU voltage
|
449
|
* of 1.2625V and CORE voltage of 1.1375V to operate at
|
450
|
* 720MHz.
|
451
|
*/
|
452
|
if (i2c_probe(PMIC_CTRL_I2C_ADDR))
|
453
|
{
|
454
|
printf("No PMIC At I2C addr %d\n", PMIC_CTRL_I2C_ADDR);
|
455
|
for(; ii < 128; ++ii)
|
456
|
if(0 == i2c_probe(ii))
|
457
|
printf("I2C device found at addr %d\n", ii);
|
458
|
return;
|
459
|
}
|
460
|
|
461
|
/* Enable the GPIO pin as output */
|
462
|
buf[0] = 0x4;
|
463
|
i2c_write(PMIC_CTRL_I2C_ADDR, PMIC_GPIO0_REG,1, buf, 1);
|
464
|
|
465
|
if (read_eeprom()) {
|
466
|
printf("read_eeprom() failure\n");
|
467
|
}
|
468
|
|
469
|
set_led_d3(1);
|
470
|
i2c_set_bus_num(I2C_PMIC_CTL_BUS);
|
471
|
|
472
|
/* Turn off pull down resistors for BOOT0P, BOOT1P. Som has
|
473
|
* pullup resistor which wastes power. */
|
474
|
buf[0] = 0;
|
475
|
if(0 != i2c_read(PMIC_CTRL_I2C_ADDR, PMIC_PUADEN_REG, 1, buf, 1)) {
|
476
|
printf("Unable to read I2C reg %d:%d.%d %x\n",
|
477
|
i2c_get_bus_num(), PMIC_CTRL_I2C_ADDR, PMIC_PUADEN_REG,
|
478
|
buf[0]);
|
479
|
}
|
480
|
buf[0] &= PMIC_PUADEN_REG_BOOTP_PD_DISABLE;
|
481
|
|
482
|
if (0 != i2c_write(PMIC_CTRL_I2C_ADDR, PMIC_PUADEN_REG, 1, buf, 1)) {
|
483
|
printf("Unable to write I2C reg %d:%d.%d %x\n",
|
484
|
i2c_get_bus_num(), PMIC_CTRL_I2C_ADDR, PMIC_PUADEN_REG,
|
485
|
buf[0]);
|
486
|
}
|
487
|
|
488
|
/* VDD1/2 voltage selection register access by control i/f */
|
489
|
buf[0] = 0;
|
490
|
if (0 != i2c_read(PMIC_CTRL_I2C_ADDR, PMIC_DEVCTRL_REG, 1, buf, 1))
|
491
|
{
|
492
|
printf("Unable to read I2C reg %d:%d.%d %x\n",
|
493
|
i2c_get_bus_num(), PMIC_CTRL_I2C_ADDR, PMIC_DEVCTRL_REG, buf[0]);
|
494
|
//return;
|
495
|
}
|
496
|
buf[0] |= PMIC_DEVCTRL_REG_SR_CTL_I2C_SEL_CTL_I2C;
|
497
|
|
498
|
if (0 != i2c_write(PMIC_CTRL_I2C_ADDR, PMIC_DEVCTRL_REG, 1, buf, 1))
|
499
|
{
|
500
|
printf("Unable to write I2C reg %d:%d.%d %x\n",
|
501
|
i2c_get_bus_num(), PMIC_CTRL_I2C_ADDR, PMIC_DEVCTRL_REG, buf[0]);
|
502
|
//return;
|
503
|
}
|
504
|
if (!voltage_update(MPU, PMIC_OP_REG_SEL_1_2_6) &&
|
505
|
!voltage_update(CORE, PMIC_OP_REG_SEL_1_1_3))
|
506
|
{
|
507
|
/* Frequency switching for OPP 120 */
|
508
|
mpu_pll_config(MPUPLL_M_720);
|
509
|
printf("PLL configuration complete\n");
|
510
|
}
|
511
|
else
|
512
|
{
|
513
|
printf("voltage update failed\n");
|
514
|
}
|
515
|
#if defined(CONFIG_SPL_ENET_SUPPORT_NOT) && defined(CONFIG_SPL_BUILD)
|
516
|
miiphy_init();
|
517
|
board_eth_init(NULL);
|
518
|
#endif
|
519
|
|
520
|
}
|
521
|
#endif
|
522
|
|
523
|
/*
|
524
|
* early system init of muxing and clocks.
|
525
|
*/
|
526
|
void s_init(void)
|
527
|
{
|
528
|
/* Can be removed as A8 comes up with L2 enabled */
|
529
|
l2_cache_enable();
|
530
|
|
531
|
|
532
|
/* WDT1 is already running when the bootloader gets control
|
533
|
* Disable it to avoid "random" resets
|
534
|
*/
|
535
|
__raw_writel(0xAAAA, WDT_WSPR);
|
536
|
while(__raw_readl(WDT_WWPS) != 0x0);
|
537
|
__raw_writel(0x5555, WDT_WSPR);
|
538
|
while(__raw_readl(WDT_WWPS) != 0x0);
|
539
|
|
540
|
#ifdef CONFIG_SPL_BUILD
|
541
|
/* Setup the PLLs and the clocks for the peripherals */
|
542
|
pll_init();
|
543
|
|
544
|
|
545
|
/* UART softreset */
|
546
|
u32 regVal;
|
547
|
u32 uart_base = DEFAULT_UART_BASE;
|
548
|
|
549
|
enable_uart0_pin_mux();
|
550
|
|
551
|
regVal = __raw_readl(uart_base + UART_SYSCFG_OFFSET);
|
552
|
regVal |= UART_RESET;
|
553
|
__raw_writel(regVal, (uart_base + UART_SYSCFG_OFFSET) );
|
554
|
while ((__raw_readl(uart_base + UART_SYSSTS_OFFSET) &
|
555
|
UART_CLK_RUNNING_MASK) != UART_CLK_RUNNING_MASK);
|
556
|
|
557
|
/* Disable smart idle */
|
558
|
regVal = __raw_readl((uart_base + UART_SYSCFG_OFFSET));
|
559
|
regVal |= UART_SMART_IDLE_EN;
|
560
|
__raw_writel(regVal, (uart_base + UART_SYSCFG_OFFSET));
|
561
|
|
562
|
/* Initialize the Timer */
|
563
|
init_timer();
|
564
|
|
565
|
preloader_console_init();
|
566
|
|
567
|
config_am335x_ddr();
|
568
|
#endif
|
569
|
|
570
|
}
|
571
|
|
572
|
/*
|
573
|
* Basic board specific setup
|
574
|
*/
|
575
|
#ifndef CONFIG_SPL_BUILD
|
576
|
int board_evm_init(void)
|
577
|
{
|
578
|
|
579
|
/* arch number of the board */
|
580
|
gd->bd->bi_arch_number = MACH_TYPE_MITYARM335X;
|
581
|
|
582
|
/* address of boot parameters */
|
583
|
gd->bd->bi_boot_params = LINUX_BOOT_PARAM_ADDR;
|
584
|
return 0;
|
585
|
}
|
586
|
#endif
|
587
|
|
588
|
int board_init(void)
|
589
|
{
|
590
|
/* Configure the i2c1 and 2 pin mux */
|
591
|
enable_i2c1_pin_mux();
|
592
|
enable_i2c2_pin_mux();
|
593
|
|
594
|
configure_evm_pin_mux(profile);
|
595
|
|
596
|
if (0 != read_eeprom())
|
597
|
{
|
598
|
printf("board_init:unable to read eeprom\n");
|
599
|
}
|
600
|
|
601
|
#ifndef CONFIG_SPL_BUILD
|
602
|
board_evm_init();
|
603
|
#endif
|
604
|
|
605
|
gpmc_init();
|
606
|
|
607
|
set_led_d3(0);
|
608
|
return 0;
|
609
|
|
610
|
configure_evm_pin_mux(profile);
|
611
|
|
612
|
#ifndef CONFIG_SPL_BUILD
|
613
|
board_evm_init();
|
614
|
#endif
|
615
|
|
616
|
gpmc_init();
|
617
|
|
618
|
return 0;
|
619
|
}
|
620
|
|
621
|
int misc_init_r(void)
|
622
|
{
|
623
|
return 0;
|
624
|
}
|
625
|
|
626
|
#define MII_EXTPAGE 0x1F
|
627
|
#define RGMII_SKEW 0x1C
|
628
|
|
629
|
static int init_vsc8601(char *name, int addr)
|
630
|
{
|
631
|
unsigned short val = 0;
|
632
|
// enable the extended page access
|
633
|
if (miiphy_write(name, addr, MII_EXTPAGE, 1) != 0) {
|
634
|
printf("Error enabling extended PHY regs\n");
|
635
|
return 1;
|
636
|
}
|
637
|
if (miiphy_read(name, addr, RGMII_SKEW, &val) != 0) {
|
638
|
printf("Error reading RGMII skew reg\n");
|
639
|
return 1;
|
640
|
}
|
641
|
val &= 0x0FFF; // clear skew values
|
642
|
val |= 0x3000; /* 0 Tx skew, 2.0ns Rx skew */
|
643
|
if (miiphy_write(name, addr, RGMII_SKEW, val) != 0) {
|
644
|
printf("failed to write RGMII_SKEW\n");
|
645
|
return 1;
|
646
|
}
|
647
|
// disable the extended page access
|
648
|
if (miiphy_write(name, addr, MII_EXTPAGE, 0) != 0) {
|
649
|
printf("Error disabling extended PHY regs\n");
|
650
|
return 1;
|
651
|
}
|
652
|
return 0;
|
653
|
}
|
654
|
|
655
|
|
656
|
#ifdef CONFIG_DRIVER_TI_CPSW
|
657
|
|
658
|
/* TODO : Check for the board specific PHY */
|
659
|
static void evm_phy_init(char *name, int addr)
|
660
|
{
|
661
|
/* TODO This currently breaks straight-up network booting and needs to be fixed. */
|
662
|
#if !defined(CONFIG_SPL_BUILD)
|
663
|
unsigned short val=0;
|
664
|
unsigned int cntr = 0;
|
665
|
unsigned short phyid1, phyid2;
|
666
|
|
667
|
/** AM3359 EVM has a Vitesse VSC8601 PHY OUI = 00010007 */
|
668
|
if(0 != miiphy_read(name, addr, MII_PHYSID1, &phyid1))
|
669
|
phyid1 = 0xDEAD;
|
670
|
if(0 != miiphy_read(name, addr, MII_PHYSID2, &phyid2))
|
671
|
phyid2 = 0xBEEF;
|
672
|
/*printf("Phy ID = %04x %04x\n", phyid1, phyid2); */
|
673
|
if(0x7 == phyid1 && 0x420 ==(phyid2& 0xFF0))
|
674
|
{
|
675
|
printf("Vitesse VSC8601 PHY detected at addr %d\n", addr);
|
676
|
val = init_vsc8601(name, addr);
|
677
|
if(0 != val)
|
678
|
printf("Error initializing VSC8601 at addr %d\n", addr);
|
679
|
}
|
680
|
/* Enable Autonegotiation */
|
681
|
if (miiphy_read(name, addr, MII_BMCR, &val) != 0) {
|
682
|
printf("failed to read bmcr on phy id %d\n", addr);
|
683
|
return;
|
684
|
}
|
685
|
|
686
|
val |= BMCR_FULLDPLX | BMCR_ANENABLE | BMCR_SPEED100;
|
687
|
|
688
|
if (miiphy_write(name, addr, MII_BMCR, val) != 0) {
|
689
|
printf("failed to write bmcr\n");
|
690
|
return;
|
691
|
}
|
692
|
miiphy_read(name, addr, MII_BMCR, &val);
|
693
|
|
694
|
/* Setup general advertisement */
|
695
|
if (miiphy_read(name, addr, MII_ADVERTISE, &val) != 0) {
|
696
|
printf("failed to read anar on phy id %d\n", addr);
|
697
|
return;
|
698
|
}
|
699
|
|
700
|
|
701
|
val |= (LPA_10HALF | LPA_10FULL | LPA_100HALF | LPA_100FULL);
|
702
|
|
703
|
if (miiphy_write(name, addr, MII_ADVERTISE, val) != 0) {
|
704
|
printf("failed to write anar on phy id %d\n", addr);
|
705
|
return;
|
706
|
}
|
707
|
miiphy_read(name, addr, MII_ADVERTISE, &val);
|
708
|
|
709
|
/* Restart auto negotiation*/
|
710
|
miiphy_read(name, addr, MII_BMCR, &val);
|
711
|
val |= BMCR_ANRESTART;
|
712
|
miiphy_write(name, addr, MII_BMCR, val);
|
713
|
|
714
|
/*check AutoNegotiate complete - it can take upto 3 secs*/
|
715
|
do {
|
716
|
udelay(40000);
|
717
|
cntr++;
|
718
|
if (!miiphy_read(name, addr, MII_BMSR, &val)) {
|
719
|
if (val & BMSR_ANEGCOMPLETE)
|
720
|
break;
|
721
|
}
|
722
|
} while (cntr < 250);
|
723
|
|
724
|
if (cntr >= 250)
|
725
|
printf("Auto negotitation failed\n");
|
726
|
else
|
727
|
printf("Auto negotiation took %d ms\n", cntr * 40);
|
728
|
|
729
|
#endif /* CONFIG_SPL_BUILD */
|
730
|
return;
|
731
|
}
|
732
|
|
733
|
static void cpsw_control(int enabled)
|
734
|
{
|
735
|
/* Enable/disable the RGMII2 port */
|
736
|
|
737
|
return;
|
738
|
}
|
739
|
|
740
|
static struct cpsw_slave_data cpsw_slaves[] = {
|
741
|
{
|
742
|
.slave_reg_ofs = 0x208,
|
743
|
.sliver_reg_ofs = 0xd80,
|
744
|
#ifdef CONFIG_SPL_ENET_SUPPORT
|
745
|
.phy_id = 1,
|
746
|
#else
|
747
|
.phy_id = 2,
|
748
|
#endif
|
749
|
},
|
750
|
{
|
751
|
.slave_reg_ofs = 0x308,
|
752
|
.sliver_reg_ofs = 0xdc0,
|
753
|
#ifdef CONFIG_SPL_ENET_SUPPORT
|
754
|
.phy_id = 2,
|
755
|
#else
|
756
|
.phy_id = 1,
|
757
|
#endif
|
758
|
},
|
759
|
};
|
760
|
static struct cpsw_platform_data cpsw_data = {
|
761
|
.mdio_base = AM335X_CPSW_MDIO_BASE,
|
762
|
.cpsw_base = AM335X_CPSW_BASE,
|
763
|
.mdio_div = 0xff,
|
764
|
.channels = 8,
|
765
|
.cpdma_reg_ofs = 0x800,
|
766
|
.slaves = 2,
|
767
|
.slave_data = cpsw_slaves,
|
768
|
.ale_reg_ofs = 0xd00,
|
769
|
.ale_entries = 1024,
|
770
|
.host_port_reg_ofs = 0x108,
|
771
|
.hw_stats_reg_ofs = 0x900,
|
772
|
.mac_control = (1 << 5) /* MIIEN */,
|
773
|
.control = cpsw_control,
|
774
|
.phy_init = evm_phy_init,
|
775
|
.gigabit_en = 1,
|
776
|
.host_port_num = 0,
|
777
|
.version = CPSW_CTRL_VERSION_2,
|
778
|
};
|
779
|
|
780
|
int board_eth_init(bd_t *bis)
|
781
|
{
|
782
|
|
783
|
uint8_t mac_addr[6];
|
784
|
uint32_t mac_hi, mac_lo;
|
785
|
int valid_mac = 0;
|
786
|
|
787
|
#ifndef CONFIG_SPL_BUILD
|
788
|
/*
|
789
|
* Environment set MAC address trumps all...
|
790
|
*/
|
791
|
if (eth_getenv_enetaddr("ethaddr", mac_addr)) {
|
792
|
valid_mac = 1;
|
793
|
}
|
794
|
/*
|
795
|
* Factory configuration MAC address overides built-in
|
796
|
*/
|
797
|
else if(is_valid_ether_addr(factory_config_block.MACADDR)) {
|
798
|
memcpy(mac_addr,factory_config_block.MACADDR, 6);
|
799
|
eth_setenv_enetaddr("ethaddr", mac_addr);
|
800
|
valid_mac = 1;
|
801
|
}
|
802
|
/* Fall back to MAC address in the eFuse eeprom in part */
|
803
|
else
|
804
|
{
|
805
|
|
806
|
debug("<ethaddr> not set. Reading from E-fuse\n");
|
807
|
/* try reading mac address from efuse */
|
808
|
#if (CONFIG_ETH_PORT == 1)
|
809
|
mac_lo = __raw_readl(MAC_ID0_LO);
|
810
|
mac_hi = __raw_readl(MAC_ID0_HI);
|
811
|
#else
|
812
|
mac_lo = __raw_readl(MAC_ID1_LO);
|
813
|
mac_hi = __raw_readl(MAC_ID1_HI);
|
814
|
#endif
|
815
|
mac_addr[0] = mac_hi & 0xFF;
|
816
|
mac_addr[1] = (mac_hi & 0xFF00) >> 8;
|
817
|
mac_addr[2] = (mac_hi & 0xFF0000) >> 16;
|
818
|
mac_addr[3] = (mac_hi & 0xFF000000) >> 24;
|
819
|
mac_addr[4] = mac_lo & 0xFF;
|
820
|
mac_addr[5] = (mac_lo & 0xFF00) >> 8;
|
821
|
|
822
|
if (is_valid_ether_addr(mac_addr)) {
|
823
|
eth_setenv_enetaddr("ethaddr", mac_addr);
|
824
|
valid_mac = 1;
|
825
|
}
|
826
|
}
|
827
|
if(valid_mac) {
|
828
|
/* Enable gigabit */
|
829
|
cpsw_data.gigabit_en = 0;
|
830
|
__raw_writel(RGMII_MODE_ENABLE, MAC_MII_SEL);
|
831
|
}
|
832
|
else {
|
833
|
printf("Warning: MAC Address not found. Ethernet disabled\n");
|
834
|
}
|
835
|
|
836
|
return cpsw_register(&cpsw_data);
|
837
|
#else
|
838
|
return 0;
|
839
|
#endif
|
840
|
}
|
841
|
#endif
|
842
|
|
843
|
#ifndef CONFIG_SPL_BUILD
|
844
|
#ifdef CONFIG_GENERIC_MMC
|
845
|
int board_mmc_init(bd_t *bis)
|
846
|
{
|
847
|
omap_mmc_init(0);
|
848
|
return 0;
|
849
|
}
|
850
|
#endif
|
851
|
|
852
|
#ifdef CONFIG_NAND_TI81XX
|
853
|
static void print_nand_ecc_info()
|
854
|
{
|
855
|
struct nand_chip *nand;
|
856
|
struct mtd_info *mtd;
|
857
|
|
858
|
if (nand_curr_device < 0 ||
|
859
|
nand_curr_device >= CONFIG_SYS_MAX_NAND_DEVICE) {
|
860
|
printf("Error: Can't switch ecc, no devices available\n");
|
861
|
return;
|
862
|
}
|
863
|
|
864
|
mtd = &nand_info[nand_curr_device];
|
865
|
nand = mtd->priv;
|
866
|
|
867
|
if(!nand)
|
868
|
{
|
869
|
printf("Error: NULL NAND device\n");
|
870
|
return;
|
871
|
}
|
872
|
switch(nand->ecc.mode) {
|
873
|
case NAND_ECC_HW:
|
874
|
printf("nand ecc mode = HW BCH8\n"); /* BCH8 is the only HW ECC mode supported */
|
875
|
break;
|
876
|
case NAND_ECC_SOFT:
|
877
|
printf("nand ecc mode = SW\n");
|
878
|
break;
|
879
|
default:
|
880
|
printf("nand ecc is disabled!\n");
|
881
|
break;
|
882
|
}
|
883
|
|
884
|
}
|
885
|
|
886
|
/******************************************************************************
|
887
|
* Command to switch between NAND HW and SW ecc
|
888
|
*****************************************************************************/
|
889
|
extern void ti81xx_nand_switch_ecc(nand_ecc_modes_t hardware, int32_t mode);
|
890
|
static int do_switch_ecc(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
|
891
|
{
|
892
|
int type = 0;
|
893
|
if (argc < 2) {
|
894
|
print_nand_ecc_info();
|
895
|
return 0;
|
896
|
}
|
897
|
if (strncmp(argv[1], "hw", 2) == 0) {
|
898
|
if (argc == 3)
|
899
|
type = simple_strtoul(argv[2], NULL, 10);
|
900
|
ti81xx_nand_switch_ecc(NAND_ECC_HW, type);
|
901
|
}
|
902
|
else if (strncmp(argv[1], "sw", 2) == 0)
|
903
|
ti81xx_nand_switch_ecc(NAND_ECC_SOFT, 0);
|
904
|
else
|
905
|
goto usage;
|
906
|
|
907
|
return 0;
|
908
|
|
909
|
usage:
|
910
|
printf("Usage: nandecc %s\n", cmdtp->usage);
|
911
|
return 1;
|
912
|
}
|
913
|
|
914
|
U_BOOT_CMD(
|
915
|
nandecc, 3, 1, do_switch_ecc,
|
916
|
"Switch NAND ECC calculation algorithm b/w hardware and software",
|
917
|
"[sw|hw <hw_type>] \n"
|
918
|
" [sw|hw]- Switch b/w hardware(hw) & software(sw) ecc algorithm\n"
|
919
|
" hw_type- 0 for Hamming code\n"
|
920
|
" 1 for bch4\n"
|
921
|
" 2 for bch8\n"
|
922
|
" 3 for bch16\n"
|
923
|
);
|
924
|
|
925
|
int board_late_init(void)
|
926
|
{
|
927
|
return 0;
|
928
|
}
|
929
|
#if 0
|
930
|
void omap_rev_string(char *str)
|
931
|
{
|
932
|
// 0x44E10000 is the CONTROL MODULE register base
|
933
|
sprintf(str, "Dev ID register = 0x%08x", *(uint32_t*)(0x44E10000));
|
934
|
}
|
935
|
#endif
|
936
|
#endif /* CONFIG_NAND_TI81XX */
|
937
|
#endif /* CONFIG_SPL_BUILD */
|