Merge commit '7b2fac7654f7420c2787f74ec3b1540fa3b343e9'
[platform/kernel/u-boot.git] / board / matrix_vision / mergerbox / mergerbox.c
1 /*
2  * Copyright (C) 2007 Freescale Semiconductor, Inc.
3  *
4  * Copyright (C) 2011 Matrix Vision GmbH
5  * Andre Schwarz <andre.schwarz@matrix-vision.de>
6  *
7  * See file CREDITS for list of people who contributed to this
8  * project.
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License as
12  * published by the Free Software Foundation; either version 2 of
13  * the License, or (at your option) any later version.
14  */
15
16 #include <common.h>
17 #include <hwconfig.h>
18 #include <i2c.h>
19 #include <spi.h>
20 #include <asm/io.h>
21 #include <asm/fsl_mpc83xx_serdes.h>
22 #include <fdt_support.h>
23 #include <spd_sdram.h>
24 #include "mergerbox.h"
25 #include "fpga.h"
26 #include "../common/mv_common.h"
27
28 static void setup_serdes(void)
29 {
30         fsl_setup_serdes(CONFIG_FSL_SERDES1, FSL_SERDES_PROTO_SATA,
31                 FSL_SERDES_CLK_100, FSL_SERDES_VDD_1V);
32         fsl_setup_serdes(CONFIG_FSL_SERDES2, FSL_SERDES_PROTO_PEX,
33                 FSL_SERDES_CLK_100, FSL_SERDES_VDD_1V);
34 }
35
36 #if defined(CONFIG_SYS_DRAM_TEST)
37 int testdram(void)
38 {
39         uint *pstart = (uint *) CONFIG_SYS_MEMTEST_START;
40         uint *pend = (uint *) CONFIG_SYS_MEMTEST_END;
41         uint *p;
42
43         printf("Testing DRAM from 0x%08x to 0x%08x\n",
44                 CONFIG_SYS_MEMTEST_START, CONFIG_SYS_MEMTEST_END);
45
46         printf("DRAM test phase 1:\n");
47         for (p = pstart; p < pend; p++)
48                 *p = 0xaaaaaaaa;
49
50         for (p = pstart; p < pend; p++) {
51                 if (*p != 0xaaaaaaaa) {
52                         printf("DRAM test fails at: %08x\n", (uint) p);
53                         return 1;
54                 }
55         }
56
57         printf("DRAM test phase 2:\n");
58         for (p = pstart; p < pend; p++)
59                 *p = 0x55555555;
60
61         for (p = pstart; p < pend; p++) {
62                 if (*p != 0x55555555) {
63                         printf("DRAM test fails at: %08x\n", (uint) p);
64                         return 1;
65                 }
66         }
67
68         printf("DRAM test passed.\n");
69         return 0;
70 }
71 #endif
72
73 phys_size_t initdram(int board_type)
74 {
75         u32 msize;
76
77         volatile immap_t *immr = (immap_t *)CONFIG_SYS_IMMR;
78         volatile clk83xx_t *clk = (clk83xx_t *)&immr->clk;
79
80         /* Enable PCI_CLK[0:1] */
81         clk->occr |= 0xc0000000;
82         udelay(2000);
83
84 #if defined(CONFIG_SPD_EEPROM)
85         msize = spd_sdram();
86 #else
87         immap_t *im = (immap_t *) CONFIG_SYS_IMMR;
88         u32 msize_log2;
89
90         msize = CONFIG_SYS_DDR_SIZE;
91         msize_log2 = __ilog2(msize);
92
93         im->sysconf.ddrlaw[0].bar = CONFIG_SYS_DDR_SDRAM_BASE & 0xfffff000;
94         im->sysconf.ddrlaw[0].ar = LBLAWAR_EN | (msize_log2 - 1);
95
96         im->sysconf.ddrcdr = CONFIG_SYS_DDRCDR_VALUE;
97         udelay(50000);
98
99         im->ddr.sdram_clk_cntl = CONFIG_SYS_DDR_SDRAM_CLK_CNTL;
100         udelay(1000);
101
102         im->ddr.csbnds[0].csbnds = CONFIG_SYS_DDR_CS0_BNDS;
103         im->ddr.cs_config[0] = CONFIG_SYS_DDR_CS0_CONFIG;
104         udelay(1000);
105
106         im->ddr.timing_cfg_0 = CONFIG_SYS_DDR_TIMING_0;
107         im->ddr.timing_cfg_1 = CONFIG_SYS_DDR_TIMING_1;
108         im->ddr.timing_cfg_2 = CONFIG_SYS_DDR_TIMING_2;
109         im->ddr.timing_cfg_3 = CONFIG_SYS_DDR_TIMING_3;
110         im->ddr.sdram_cfg = CONFIG_SYS_DDR_SDRAM_CFG;
111         im->ddr.sdram_cfg2 = CONFIG_SYS_DDR_SDRAM_CFG2;
112         im->ddr.sdram_mode = CONFIG_SYS_DDR_MODE;
113         im->ddr.sdram_mode2 = CONFIG_SYS_DDR_MODE2;
114         im->ddr.sdram_interval = CONFIG_SYS_DDR_INTERVAL;
115         __asm__ __volatile__("sync");
116         udelay(1000);
117
118         im->ddr.sdram_cfg |= SDRAM_CFG_MEM_EN;
119         udelay(2000);
120 #endif
121         setup_serdes();
122
123         return msize << 20;
124 }
125
126 int checkboard(void)
127 {
128         puts("Board: Matrix Vision MergerBox\n");
129
130         return 0;
131 }
132
133 int misc_init_r(void)
134 {
135         u16 dim;
136         int result;
137         volatile immap_t *immr = (immap_t *)CONFIG_SYS_IMMR;
138         volatile gpio83xx_t *gpio = (gpio83xx_t *)&immr->gpio[1];
139         unsigned char mac[6], mac_verify[6];
140         char *s = getenv("reset_env");
141
142         for (dim = 10; dim < 180; dim += 5) {
143                 mergerbox_tft_dim(dim);
144                 udelay(100000);
145         }
146
147         if (s)
148                 mv_reset_environment();
149
150         i2c_read(SPD_EEPROM_ADDRESS, 0x80, 2, mac, sizeof(mac));
151
152         /* check if Matrix Vision prefix present and export to env */
153         if (mac[0] == 0x00 && mac[1] == 0x0c && mac[2] == 0x8d) {
154                 printf("valid MAC found in eeprom: %pM\n", mac);
155                 eth_setenv_enetaddr("ethaddr", mac);
156         } else {
157                 printf("no valid MAC found in eeprom.\n");
158
159                 /* no: check the env */
160                 if (!eth_getenv_enetaddr("ethaddr", mac)) {
161                         printf("no valid MAC found in env either.\n");
162                         /* TODO: ask for valid MAC */
163                 } else {
164                         printf("valid MAC found in env: %pM\n", mac);
165                         printf("updating MAC in eeprom.\n");
166
167                         do {
168                                 result = test_and_clear_bit(20, &gpio->dat);
169                                 if (result)
170                                         printf("unprotect EEPROM failed !\n");
171                                 udelay(20000);
172                         } while(result);
173
174                         i2c_write(SPD_EEPROM_ADDRESS, 0x80, 2, mac, 6);
175                         udelay(20000);
176
177                         do {
178                                 result = test_and_set_bit(20, &gpio->dat);
179                                 if (result)
180                                         printf("protect EEPROM failed !\n");
181                                 udelay(20000);
182                         } while(result);
183
184                         printf("verify MAC %pM ... ", mac);
185                         i2c_read(SPD_EEPROM_ADDRESS, 0x80, 2, mac_verify, 6);
186
187                         if (!strncmp((char *)mac, (char *)mac_verify, 6))
188                                 printf("ok.\n");
189                         else
190                                 /* TODO: retry or do something useful */
191                                 printf("FAILED (got %pM) !\n", mac_verify);
192                 }
193         }
194
195         return 0;
196 }
197
198 int spi_cs_is_valid(unsigned int bus, unsigned int cs)
199 {
200         return bus == 0 && cs == 0;
201 }
202
203 void spi_cs_activate(struct spi_slave *slave)
204 {
205         volatile gpio83xx_t *iopd = &((immap_t *)CONFIG_SYS_IMMR)->gpio[0];
206
207         iopd->dat &= ~TFT_SPI_CPLD_CS;
208 }
209
210 void spi_cs_deactivate(struct spi_slave *slave)
211 {
212         volatile gpio83xx_t *iopd = &((immap_t *)CONFIG_SYS_IMMR)->gpio[0];
213
214         iopd->dat |= TFT_SPI_CPLD_CS;
215 }
216
217 /* control backlight pwm (display brightness).
218  * allow values 0-250 with 0 = turn off and 250 = max brightness
219  */
220 void mergerbox_tft_dim(u16 value)
221 {
222         struct spi_slave *slave;
223         u16 din;
224         u16 dout = 0;
225
226         if (value > 0 && value < 250)
227                 dout = 0x4000 | value;
228
229         slave = spi_setup_slave(0, 0, 1000000, SPI_MODE_0 | SPI_CS_HIGH);
230         spi_claim_bus(slave);
231         spi_xfer(slave, 16, &dout, &din, SPI_XFER_BEGIN | SPI_XFER_END);
232         spi_release_bus(slave);
233         spi_free_slave(slave);
234 }
235
236 void ft_board_setup(void *blob, bd_t *bd)
237 {
238         ft_cpu_setup(blob, bd);
239         fdt_fixup_dr_usb(blob, bd);
240         ft_pci_setup(blob, bd);
241 }