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