85xx: socrates: Enable Lime support.
[kernel/u-boot.git] / board / socrates / socrates.c
1 /*
2  * (C) Copyright 2008
3  * Sergei Poselenov, Emcraft Systems, sposelenov@emcraft.com.
4  *
5  * Copyright 2004 Freescale Semiconductor.
6  * (C) Copyright 2002,2003, Motorola Inc.
7  * Xianghua Xiao, (X.Xiao@motorola.com)
8  *
9  * (C) Copyright 2002 Scott McNutt <smcnutt@artesyncp.com>
10  *
11  * See file CREDITS for list of people who contributed to this
12  * project.
13  *
14  * This program is free software; you can redistribute it and/or
15  * modify it under the terms of the GNU General Public License as
16  * published by the Free Software Foundation; either version 2 of
17  * the License, or (at your option) any later version.
18  *
19  * This program is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the
22  * GNU General Public License for more details.
23  *
24  * You should have received a copy of the GNU General Public License
25  * along with this program; if not, write to the Free Software
26  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
27  * MA 02111-1307 USA
28  */
29
30 #include <common.h>
31 #include <pci.h>
32 #include <asm/processor.h>
33 #include <asm/immap_85xx.h>
34 #include <ioports.h>
35 #include <flash.h>
36 #include <libfdt.h>
37 #include <fdt_support.h>
38 #include <asm/io.h>
39
40 #include "upm_table.h"
41
42 DECLARE_GLOBAL_DATA_PTR;
43
44 extern flash_info_t flash_info[];       /* FLASH chips info */
45
46 void local_bus_init (void);
47 ulong flash_get_size (ulong base, int banknum);
48
49 int checkboard (void)
50 {
51         volatile ccsr_gur_t *gur = (void *)(CFG_MPC85xx_GUTS_ADDR);
52
53         char *src;
54         int f;
55         char *s = getenv("serial#");
56
57         puts("Board: Socrates");
58         if (s != NULL) {
59                 puts(", serial# ");
60                 puts(s);
61         }
62         putc('\n');
63
64 #ifdef CONFIG_PCI
65         /* Check the PCI_clk sel bit */
66         if (in_be32(&gur->porpllsr) & (1<<15)) {
67                 src = "SYSCLK";
68                 f = CONFIG_SYS_CLK_FREQ;
69         } else {
70                 src = "PCI_CLK";
71                 f = CONFIG_PCI_CLK_FREQ;
72         }
73         printf ("PCI1:  32 bit, %d MHz (%s)\n", f/1000000, src);
74 #else
75         printf ("PCI1:  disabled\n");
76 #endif
77
78         /*
79          * Initialize local bus.
80          */
81         local_bus_init ();
82         return 0;
83 }
84
85 int misc_init_r (void)
86 {
87         volatile ccsr_lbc_t *memctl = (void *)(CFG_MPC85xx_LBC_ADDR);
88
89         /*
90          * Adjust flash start and offset to detected values
91          */
92         gd->bd->bi_flashstart = 0 - gd->bd->bi_flashsize;
93         gd->bd->bi_flashoffset = 0;
94
95         /*
96          * Check if boot FLASH isn't max size
97          */
98         if (gd->bd->bi_flashsize < (0 - CFG_FLASH0)) {
99                 memctl->or0 = gd->bd->bi_flashstart | (CFG_OR0_PRELIM & 0x00007fff);
100                 memctl->br0 = gd->bd->bi_flashstart | (CFG_BR0_PRELIM & 0x00007fff);
101
102                 /*
103                  * Re-check to get correct base address
104                  */
105                 flash_get_size(gd->bd->bi_flashstart, CFG_MAX_FLASH_BANKS - 1);
106         }
107
108         /*
109          * Check if only one FLASH bank is available
110          */
111         if (gd->bd->bi_flashsize != CFG_MAX_FLASH_BANKS * (0 - CFG_FLASH0)) {
112                 memctl->or1 = 0;
113                 memctl->br1 = 0;
114
115                 /*
116                  * Re-do flash protection upon new addresses
117                  */
118                 flash_protect (FLAG_PROTECT_CLEAR,
119                                gd->bd->bi_flashstart, 0xffffffff,
120                                &flash_info[CFG_MAX_FLASH_BANKS - 1]);
121
122                 /* Monitor protection ON by default */
123                 flash_protect (FLAG_PROTECT_SET,
124                                CFG_MONITOR_BASE, CFG_MONITOR_BASE + monitor_flash_len - 1,
125                                &flash_info[CFG_MAX_FLASH_BANKS - 1]);
126
127                 /* Environment protection ON by default */
128                 flash_protect (FLAG_PROTECT_SET,
129                                CFG_ENV_ADDR,
130                                CFG_ENV_ADDR + CFG_ENV_SECT_SIZE - 1,
131                                &flash_info[CFG_MAX_FLASH_BANKS - 1]);
132
133                 /* Redundant environment protection ON by default */
134                 flash_protect (FLAG_PROTECT_SET,
135                                CFG_ENV_ADDR_REDUND,
136                                CFG_ENV_ADDR_REDUND + CFG_ENV_SIZE_REDUND - 1,
137                                &flash_info[CFG_MAX_FLASH_BANKS - 1]);
138         }
139
140         return 0;
141 }
142
143 /*
144  * Initialize Local Bus
145  */
146 void local_bus_init (void)
147 {
148         volatile ccsr_lbc_t *lbc = (void *)(CFG_MPC85xx_LBC_ADDR);
149         volatile ccsr_local_ecm_t *ecm = (void *)(CFG_MPC85xx_ECM_ADDR);
150         sys_info_t sysinfo;
151         uint clkdiv;
152         uint lbc_mhz;
153         uint lcrr = CFG_LBC_LCRR;
154
155         get_sys_info (&sysinfo);
156         clkdiv = lbc->lcrr & 0x0f;
157         lbc_mhz = sysinfo.freqSystemBus / 1000000 / clkdiv;
158
159         /* Disable PLL bypass for Local Bus Clock >= 66 MHz */
160         if (lbc_mhz >= 66)
161                 lcrr &= ~LCRR_DBYP;     /* DLL Enabled */
162         else
163                 lcrr |= LCRR_DBYP;      /* DLL Bypass */
164
165         out_be32 (&lbc->lcrr, lcrr);
166         asm ("sync;isync;msync");
167
168         out_be32 (&lbc->ltesr, 0xffffffff);     /* Clear LBC error interrupts */
169         out_be32 (&lbc->lteir, 0xffffffff);     /* Enable LBC error interrupts */
170         out_be32 (&ecm->eedr, 0xffffffff);      /* Clear ecm errors */
171         out_be32 (&ecm->eeer, 0xffffffff);      /* Enable ecm errors */
172
173         /* Init UPMA for FPGA access */
174         out_be32 (&lbc->mamr, 0x44440); /* Use a customer-supplied value */
175         upmconfig (UPMA, (uint *)UPMTableA, sizeof(UPMTableA)/sizeof(int));
176
177         if (getenv("lime")) {
178                 /* Init UPMB for Lime controller access */
179                 out_be32 (&lbc->mbmr, 0x444440); /* Use a customer-supplied value */
180                 upmconfig (UPMB, (uint *)UPMTableB, sizeof(UPMTableB)/sizeof(int));
181         }
182 }
183
184 #if defined(CONFIG_PCI)
185 /*
186  * Initialize PCI Devices, report devices found.
187  */
188
189 #ifndef CONFIG_PCI_PNP
190 static struct pci_config_table pci_mpc85xxads_config_table[] = {
191         {PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
192          PCI_IDSEL_NUMBER, PCI_ANY_ID,
193          pci_cfgfunc_config_device, {PCI_ENET0_IOADDR,
194                                      PCI_ENET0_MEMADDR,
195                                      PCI_COMMAND_MEMORY |
196                                      PCI_COMMAND_MASTER}},
197         {}
198 };
199 #endif
200
201
202 static struct pci_controller hose = {
203 #ifndef CONFIG_PCI_PNP
204         config_table:pci_mpc85xxads_config_table,
205 #endif
206 };
207
208 #endif /* CONFIG_PCI */
209
210
211 void pci_init_board (void)
212 {
213 #ifdef CONFIG_PCI
214         pci_mpc85xx_init (&hose);
215 #endif /* CONFIG_PCI */
216 }
217
218 #ifdef CONFIG_BOARD_EARLY_INIT_R
219 int board_early_init_r (void)
220 {
221         volatile ccsr_gur_t *gur = (void *)(CFG_MPC85xx_GUTS_ADDR);
222
223         /* set and reset the GPIO pin 2 which will reset the W83782G chip */
224         out_8((unsigned char*)&gur->gpoutdr, 0x3F );
225         out_be32((unsigned int*)&gur->gpiocr, 0x200 );  /* enable GPOut */
226         udelay(200);
227         out_8( (unsigned char*)&gur->gpoutdr, 0x1F );
228
229         return (0);
230 }
231 #endif /* CONFIG_BOARD_EARLY_INIT_R */
232
233 #if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_OF_BOARD_SETUP)
234 void
235 ft_board_setup(void *blob, bd_t *bd)
236 {
237         u32 val[12];
238         int rc, i = 0;
239
240         ft_cpu_setup(blob, bd);
241
242         /* Fixup NOR FLASH mapping */
243         val[i++] = 0;                           /* chip select number */
244         val[i++] = 0;                           /* always 0 */
245         val[i++] = gd->bd->bi_flashstart;
246         val[i++] = gd->bd->bi_flashsize;
247
248         if (getenv("lime")) {
249                 /* Fixup LIME mapping */
250                 val[i++] = 2;                   /* chip select number */
251                 val[i++] = 0;                   /* always 0 */
252                 val[i++] = CFG_LIME_BASE;
253                 val[i++] = CFG_LIME_SIZE;
254         }
255
256         /* Fixup FPGA mapping */
257         val[i++] = 3;                           /* chip select number */
258         val[i++] = 0;                           /* always 0 */
259         val[i++] = CFG_FPGA_BASE;
260         val[i++] = CFG_FPGA_SIZE;
261
262         rc = fdt_find_and_setprop(blob, "/localbus", "ranges",
263                                   val, i * sizeof(u32), 1);
264         if (rc)
265                 printf("Unable to update localbus ranges, err=%s\n",
266                        fdt_strerror(rc));
267 }
268 #endif /* defined(CONFIG_OF_LIBFDT) && defined(CONFIG_OF_BOARD_SETUP) */
269
270 #include <i2c.h>
271 #include <mb862xx.h>
272 #include <video_fb.h>
273
274 #define CFG_LIME_SRST           ((CFG_LIME_BASE) + 0x01FC002C)
275 #define CFG_LIME_CCF            ((CFG_LIME_BASE) + 0x01FC0038)
276 #define CFG_LIME_MMR            ((CFG_LIME_BASE) + 0x01FCFFFC)
277 /* Lime clock frequency */
278 #define CFG_LIME_CLK_100MHZ     0x00000
279 #define CFG_LIME_CLK_133MHZ     0x10000
280 /* SDRAM parameter */
281 #define CFG_LIME_MMR_VALUE      0x4157BA63
282
283 #define DISPLAY_WIDTH           800
284 #define DISPLAY_HEIGHT          480
285 #define DEFAULT_BRIGHTNESS      25
286 #define BACKLIGHT_ENABLE        (1 << 31)
287
288 extern GraphicDevice mb862xx;
289
290 static const gdc_regs init_regs [] =
291 {
292         {0x0100, 0x00010f00},
293         {0x0020, 0x801901df},
294         {0x0024, 0x00000000},
295         {0x0028, 0x00000000},
296         {0x002c, 0x00000000},
297         {0x0110, 0x00000000},
298         {0x0114, 0x00000000},
299         {0x0118, 0x01df0320},
300         {0x0004, 0x041f0000},
301         {0x0008, 0x031f031f},
302         {0x000c, 0x017f0349},
303         {0x0010, 0x020c0000},
304         {0x0014, 0x01df01e9},
305         {0x0018, 0x00000000},
306         {0x001c, 0x01e00320},
307         {0x0100, 0x80010f00},
308         {0x0, 0x0}
309 };
310
311 const gdc_regs *board_get_regs (void)
312 {
313         return init_regs;
314 }
315
316 /* Returns Lime base address */
317 unsigned int board_video_init (void)
318 {
319
320         if (!getenv("lime"))
321                 return 0;
322
323         /*
324          * Reset Lime controller
325          */
326         out_be32((void *)CFG_LIME_SRST, 0x1);
327         udelay(200);
328
329         /* Set Lime clock to 133MHz */
330         out_be32((void *)CFG_LIME_CCF, CFG_LIME_CLK_133MHZ);
331         /* Delay required */
332         udelay(300);
333         /* Set memory parameters */
334         out_be32((void *)CFG_LIME_MMR, CFG_LIME_MMR_VALUE);
335
336         mb862xx.winSizeX = DISPLAY_WIDTH;
337         mb862xx.winSizeY = DISPLAY_HEIGHT;
338         mb862xx.gdfIndex = GDF_15BIT_555RGB;
339         mb862xx.gdfBytesPP = 2;
340
341         return CFG_LIME_BASE;
342 }
343
344 #define W83782D_REG_CFG         0x40
345 #define W83782D_REG_BANK_SEL    0x4e
346 #define W83782D_REG_ADCCLK      0x4b
347 #define W83782D_REG_BEEP_CTRL   0x4d
348 #define W83782D_REG_BEEP_CTRL2  0x57
349 #define W83782D_REG_PWMOUT1     0x5b
350 #define W83782D_REG_VBAT        0x5d
351
352 static int w83782d_hwmon_init(void)
353 {
354         u8 buf;
355
356         if (i2c_read(CFG_I2C_W83782G_ADDR, W83782D_REG_CFG, 1, &buf, 1))
357                 return -1;
358
359         i2c_reg_write(CFG_I2C_W83782G_ADDR, W83782D_REG_CFG, 0x80);
360         i2c_reg_write(CFG_I2C_W83782G_ADDR, W83782D_REG_BANK_SEL, 0);
361         i2c_reg_write(CFG_I2C_W83782G_ADDR, W83782D_REG_ADCCLK, 0x40);
362
363         buf = i2c_reg_read(CFG_I2C_W83782G_ADDR, W83782D_REG_BEEP_CTRL);
364         i2c_reg_write(CFG_I2C_W83782G_ADDR, W83782D_REG_BEEP_CTRL,
365                       buf | 0x80);
366         i2c_reg_write(CFG_I2C_W83782G_ADDR, W83782D_REG_BEEP_CTRL2, 0);
367         i2c_reg_write(CFG_I2C_W83782G_ADDR, W83782D_REG_PWMOUT1, 0x47);
368         i2c_reg_write(CFG_I2C_W83782G_ADDR, W83782D_REG_VBAT, 0x01);
369
370         buf = i2c_reg_read(CFG_I2C_W83782G_ADDR, W83782D_REG_CFG);
371         i2c_reg_write(CFG_I2C_W83782G_ADDR, W83782D_REG_CFG,
372                       (buf & 0xf4) | 0x01);
373         return 0;
374 }
375
376 static void board_backlight_brightness(int br)
377 {
378         u32 reg;
379         u8 buf;
380         u8 old_buf;
381
382         /* Select bank 0 */
383         if (i2c_read(CFG_I2C_W83782G_ADDR, 0x4e, 1, &old_buf, 1))
384                 goto err;
385         else
386                 buf = old_buf & 0xf8;
387
388         if (i2c_write(CFG_I2C_W83782G_ADDR, 0x4e, 1, &buf, 1))
389                 goto err;
390
391         if (br > 0) {
392                 /* PWMOUT1 duty cycle ctrl */
393                 buf = 255 / (100 / br);
394                 if (i2c_write(CFG_I2C_W83782G_ADDR, 0x5b, 1, &buf, 1))
395                         goto err;
396
397                 /* LEDs on */
398                 reg = in_be32((void *)(CFG_FPGA_BASE + 0x0c));
399                 if (!(reg & BACKLIGHT_ENABLE));
400                         out_be32((void *)(CFG_FPGA_BASE + 0x0c),
401                                  reg | BACKLIGHT_ENABLE);
402         } else {
403                 buf = 0;
404                 if (i2c_write(CFG_I2C_W83782G_ADDR, 0x5b, 1, &buf, 1))
405                         goto err;
406
407                 /* LEDs off */
408                 reg = in_be32((void *)(CFG_FPGA_BASE + 0x0c));
409                 reg &= ~BACKLIGHT_ENABLE;
410                 out_be32((void *)(CFG_FPGA_BASE + 0x0c), reg);
411         }
412         /* Restore previous bank setting */
413         if (i2c_write(CFG_I2C_W83782G_ADDR, 0x4e, 1, &old_buf, 1))
414                 goto err;
415
416         return;
417 err:
418         printf("W83782G I2C access failed\n");
419 }
420
421 void board_backlight_switch (int flag)
422 {
423         char * param;
424         int rc;
425
426         if (w83782d_hwmon_init())
427                 printf ("hwmon IC init failed\n");
428
429         if (flag) {
430                 param = getenv("brightness");
431                 rc = param ? simple_strtol(param, NULL, 10) : -1;
432                 if (rc < 0)
433                         rc = DEFAULT_BRIGHTNESS;
434         } else {
435                 rc = 0;
436         }
437         board_backlight_brightness(rc);
438 }
439
440 #if defined(CONFIG_CONSOLE_EXTRA_INFO)
441 /*
442  * Return text to be printed besides the logo.
443  */
444 void video_get_info_str (int line_number, char *info)
445 {
446         if (line_number == 1) {
447                 strcpy (info, " Board: Socrates");
448         } else {
449                 info [0] = '\0';
450         }
451 }
452 #endif