blob: 8cf7beea72d379eaed42d11d4c82cb724cd40a33 [file] [log] [blame]
Ira W. Snyder98397092011-11-23 08:25:58 -08001/*
2 * Copyright 2009 Freescale Semiconductor, Inc.
3 *
4 * See file CREDITS for list of people who contributed to this
5 * project.
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; either version 2 of
10 * the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
20 * MA 02111-1307 USA
21 */
22
23#include <common.h>
24#include <hwconfig.h>
25#include <command.h>
26#include <asm/processor.h>
27#include <asm/mmu.h>
28#include <asm/cache.h>
29#include <asm/immap_85xx.h>
30#include <asm/mpc85xx_gpio.h>
31#include <asm/fsl_serdes.h>
32#include <asm/io.h>
33#include <miiphy.h>
34#include <libfdt.h>
35#include <fdt_support.h>
36#include <fsl_mdio.h>
37#include <tsec.h>
38#include <vsc7385.h>
39#include <netdev.h>
40#include <mmc.h>
41#include <malloc.h>
42#include <i2c.h>
43
44#if defined(CONFIG_PCI)
45#include <asm/fsl_pci.h>
46#include <pci.h>
47#endif
48
49DECLARE_GLOBAL_DATA_PTR;
50
51#if defined(CONFIG_PCI)
52void pci_init_board(void)
53{
54 fsl_pcie_init_board(0);
55}
56
57void ft_pci_board_setup(void *blob)
58{
59 FT_FSL_PCI_SETUP;
60}
61#endif
62
63#define BOARD_PERI_RST_SET (VSC7385_RST_SET | SLIC_RST_SET | \
64 SGMII_PHY_RST_SET | PCIE_RST_SET | \
65 RGMII_PHY_RST_SET)
66
67#define SYSCLK_MASK 0x00200000
68#define BOARDREV_MASK 0x10100000
69#define BOARDREV_B 0x10100000
70#define BOARDREV_C 0x00100000
71#define BOARDREV_D 0x00000000
72
73#define SYSCLK_66 66666666
74#define SYSCLK_50 50000000
75#define SYSCLK_100 100000000
76
77unsigned long get_board_sys_clk(ulong dummy)
78{
79 ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
80 u32 ddr_ratio = in_be32(&gur->porpllsr) & MPC85xx_PORPLLSR_DDR_RATIO;
81
82 ddr_ratio >>= MPC85xx_PORPLLSR_DDR_RATIO_SHIFT;
83 switch (ddr_ratio) {
84 case 0x0C:
85 return SYSCLK_66;
86 case 0x0A:
87 case 0x08:
88 return SYSCLK_100;
89 default:
90 puts("ERROR: unknown DDR ratio\n");
91 return SYSCLK_100;
92 }
93}
94
95unsigned long get_board_ddr_clk(ulong dummy)
96{
97 ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
98 u32 ddr_ratio = in_be32(&gur->porpllsr) & MPC85xx_PORPLLSR_DDR_RATIO;
99
100 ddr_ratio >>= MPC85xx_PORPLLSR_DDR_RATIO_SHIFT;
101 switch (ddr_ratio) {
102 case 0x0C:
103 case 0x0A:
104 return SYSCLK_66;
105 case 0x08:
106 return SYSCLK_100;
107 default:
108 puts("ERROR: unknown DDR ratio\n");
109 return SYSCLK_100;
110 }
111}
112
113#ifdef CONFIG_MMC
114int board_early_init_f(void)
115{
116 ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
117
118 setbits_be32(&gur->pmuxcr,
119 (MPC85xx_PMUXCR_SDHC_CD |
120 MPC85xx_PMUXCR_SDHC_WP));
121
122 /* All the device are enable except for SRIO12 */
123 setbits_be32(&gur->devdisr, MPC85xx_DEVDISR_SRIO);
124 return 0;
125}
126#endif
127
128#define GPIO_DIR 0x0f3a0000
129#define GPIO_ODR 0x00000000
130#define GPIO_DAT 0x001a0000
131
132int checkboard(void)
133{
134 ccsr_gpio_t *pgpio = (void *)(CONFIG_SYS_MPC85xx_GPIO_ADDR + 0xC00);
135
136 /*
137 * GPIO
138 * 0 - 3: CarryBoard Input;
139 * 4 - 7: CarryBoard Output;
140 * 8 : Mux as SDHC_CD (card detection)
141 * 9 : Mux as SDHC_WP
142 * 10 : Clear Watchdog timer
143 * 11 : LED Input
144 * 12 : Output to 1
145 * 13 : Open Drain
146 * 14 : LED Output
147 * 15 : Switch Input
148 *
149 * Set GPIOs 11, 12, 14 to 1.
150 */
151 out_be32(&pgpio->gpodr, GPIO_ODR);
152 mpc85xx_gpio_set(0xffffffff, GPIO_DIR, GPIO_DAT);
153
154 puts("Board: Freescale COM Express P2020\n");
155 return 0;
156}
157
158#define M41ST85W_I2C_BUS 1
159#define M41ST85W_I2C_ADDR 0x68
160#define M41ST85W_ERROR(fmt, args...) printf("ERROR: M41ST85W: " fmt, ##args)
161
162static void m41st85w_clear_bit(u8 reg, u8 mask, const char *name)
163{
164 u8 data;
165
166 if (i2c_read(M41ST85W_I2C_ADDR, reg, 1, &data, 1)) {
167 M41ST85W_ERROR("unable to read %s bit\n", name);
168 return;
169 }
170
171 if (data & mask) {
172 data &= ~mask;
173 if (i2c_write(M41ST85W_I2C_ADDR, reg, 1, &data, 1)) {
174 M41ST85W_ERROR("unable to clear %s bit\n", name);
175 return;
176 }
177 }
178}
179
180#define M41ST85W_REG_SEC2 0x01
181#define M41ST85W_REG_SEC2_ST 0x80
182
183#define M41ST85W_REG_ALHOUR 0x0c
184#define M41ST85W_REG_ALHOUR_HT 0x40
185
186/*
187 * The P2020COME board has a STMicro M41ST85W RTC/watchdog
188 * at i2c bus 1 address 0x68.
189 */
190static void start_rtc(void)
191{
192 unsigned int bus = i2c_get_bus_num();
193
194 if (i2c_set_bus_num(M41ST85W_I2C_BUS)) {
195 M41ST85W_ERROR("unable to set i2c bus\n");
196 goto out;
197 }
198
199 /* ensure ST (stop) and HT (halt update) bits are cleared */
200 m41st85w_clear_bit(M41ST85W_REG_SEC2, M41ST85W_REG_SEC2_ST, "ST");
201 m41st85w_clear_bit(M41ST85W_REG_ALHOUR, M41ST85W_REG_ALHOUR_HT, "HT");
202
203out:
204 /* reset the i2c bus */
205 i2c_set_bus_num(bus);
206}
207
208int board_early_init_r(void)
209{
210 start_rtc();
211 return 0;
212}
213
214#define M41ST85W_REG_WATCHDOG 0x09
215#define M41ST85W_REG_WATCHDOG_WDS 0x80
216#define M41ST85W_REG_WATCHDOG_BMB0 0x04
217
218void board_reset(void)
219{
220 u8 data = M41ST85W_REG_WATCHDOG_WDS | M41ST85W_REG_WATCHDOG_BMB0;
221
222 /* set the hardware watchdog timeout to 1/16 second, then hang */
223 i2c_set_bus_num(M41ST85W_I2C_BUS);
224 i2c_write(M41ST85W_I2C_ADDR, M41ST85W_REG_WATCHDOG, 1, &data, 1);
225
226 while (1)
227 /* hang */;
228}
229
230#ifdef CONFIG_TSEC_ENET
231int board_eth_init(bd_t *bis)
232{
233 struct fsl_pq_mdio_info mdio_info;
234 struct tsec_info_struct tsec_info[4];
235 int num = 0;
236
237#ifdef CONFIG_TSEC1
238 SET_STD_TSEC_INFO(tsec_info[num], 1);
239 num++;
240#endif
241#ifdef CONFIG_TSEC2
242 SET_STD_TSEC_INFO(tsec_info[num], 2);
243 num++;
244#endif
245#ifdef CONFIG_TSEC3
246 SET_STD_TSEC_INFO(tsec_info[num], 3);
247 if (is_serdes_configured(SGMII_TSEC3)) {
248 puts("eTSEC3 is in sgmii mode.");
249 tsec_info[num].flags |= TSEC_SGMII;
250 }
251 num++;
252#endif
253 if (!num) {
254 printf("No TSECs initialized\n");
255 return 0;
256 }
257
258 mdio_info.regs = (struct tsec_mii_mng *)CONFIG_SYS_MDIO_BASE_ADDR;
259 mdio_info.name = DEFAULT_MII_NAME;
260 fsl_pq_mdio_init(bis, &mdio_info);
261
262 tsec_eth_init(bis, tsec_info, num);
263
264 return pci_eth_init(bis);
265}
266#endif
267
268#if defined(CONFIG_OF_BOARD_SETUP)
269void ft_board_setup(void *blob, bd_t *bd)
270{
271 phys_addr_t base;
272 phys_size_t size;
273
274 ft_cpu_setup(blob, bd);
275
276 base = getenv_bootm_low();
277 size = getenv_bootm_size();
278
279#if defined(CONFIG_PCI)
280 ft_pci_board_setup(blob);
281#endif
282
283 fdt_fixup_memory(blob, (u64)base, (u64)size);
284
285 fdt_fixup_dr_usb(blob, bd);
286}
287#endif