1/*  *********************************************************************
2    *  Broadcom Common Firmware Environment (CFE)
3    *
4    *  LAUSANNE-specific commands		      File: ui_lausanne.c
5    *
6    *  A temporary sandbox for misc test routines and commands.
7    *
8    *  Author:  Mitch Lichtenberg
9    *
10    *********************************************************************
11    *
12    *  Copyright 2000,2001,2002,2003,2004
13    *  Broadcom Corporation. All rights reserved.
14    *
15    *  This software is furnished under license and may be used and
16    *  copied only in accordance with the following terms and
17    *  conditions.  Subject to these conditions, you may download,
18    *  copy, install, use, modify and distribute modified or unmodified
19    *  copies of this software in source and/or binary form.  No title
20    *  or ownership is transferred hereby.
21    *
22    *  1) Any source code used, modified or distributed must reproduce
23    *     and retain this copyright notice and list of conditions
24    *     as they appear in the source file.
25    *
26    *  2) No right is granted to use any trade name, trademark, or
27    *     logo of Broadcom Corporation.  The "Broadcom Corporation"
28    *     name may not be used to endorse or promote products derived
29    *     from this software without the prior written permission of
30    *     Broadcom Corporation.
31    *
32    *  3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR
33    *     IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED
34    *     WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
35    *     PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT
36    *     SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN
37    *     PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT,
38    *     INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
39    *     (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
40    *     GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
41    *     BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
42    *     OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
43    *     TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF
44    *     THE POSSIBILITY OF SUCH DAMAGE.
45    ********************************************************************* */
46
47
48#include "cfe.h"
49#include "ui_command.h"
50#if CFG_PCI
51#include "pcivar.h"
52#endif
53
54#include "sbmips.h"
55#include "sb1250_regs.h"
56#include "sb1250_genbus.h"
57#include "lausanne.h"
58
59
60/*  *********************************************************************
61    *  Configuration
62    ********************************************************************* */
63
64#ifndef DEBUG_CS
65#define DEBUG_CS  0
66#endif
67
68
69/*  *********************************************************************
70    *  prototypes
71    ********************************************************************* */
72
73int ui_init_swarmcmds(void);
74
75int ui_init_cpldcmds(void);
76static int ui_cmd_writecpld(ui_cmdline_t *cmd,int argc,char *argv[]);
77static int ui_cmd_readcpld(ui_cmdline_t *cmd,int argc,char *argv[]);
78static int ui_cmd_burstwcpld(ui_cmdline_t *cmd,int argc,char *argv[]);
79static int ui_cmd_burstrcpld(ui_cmdline_t *cmd,int argc,char *argv[]);
80static int ui_cmd_config_flash(ui_cmdline_t *cmd,int argc,char *argv[]);
81
82#if CFG_PCI
83static int ui_cmd_map_pci(ui_cmdline_t *cmd,int argc,char *argv[]);
84#endif
85
86#if CFG_VGACONSOLE
87static int ui_cmd_vgadump(ui_cmdline_t *cmd,int argc,char *argv[]);
88static int ui_cmd_vgainit(ui_cmdline_t *cmd,int argc,char *argv[]);
89extern int vga_biosinit(void);
90extern void vgaraw_dump(char *tail);
91#endif
92
93static int burst_mode(unsigned int cs, int burst_on);
94static int intel_flash_data_width_mode(unsigned int cs, int flash_16bit);
95
96
97/*  *********************************************************************
98    *  Data
99    ********************************************************************* */
100
101
102/*  *********************************************************************
103    *  ui_init_swarmcmds()
104    *
105    *  Add SWARM-specific commands to the command table
106    *
107    *  Input parameters:
108    *  	   nothing
109    *
110    *  Return value:
111    *  	   0
112    ********************************************************************* */
113
114
115int ui_init_swarmcmds(void)
116{
117#if CFG_PCI
118    cmd_addcmd("map pci",
119	       ui_cmd_map_pci,
120	       NULL,
121	       "Define a BAR0 window available to PCI devices",
122	       "map pci offset size paddr [-off] [-l2ca] [-matchbits]\n\n"
123	       "Map the region of size bytes starting at paddr to appear\n"
124	       "at offset relative to BAR0\n",
125	       "-off;Remove the region|"
126	       "-l2ca;Make L2 cachable|"
127	       "-matchbits;Use match bits policy");
128#endif
129#if CFG_VGACONSOLE
130    cmd_addcmd("vga init",
131	       ui_cmd_vgainit,
132	       NULL,
133	       "Initialize the VGA adapter.",
134	       "vgainit",
135	       "");
136
137    cmd_addcmd("vga dumpbios",
138	       ui_cmd_vgadump,
139	       NULL,
140	       "Dump the VGA BIOS to the console",
141	       "vga dumpbios",
142	       "");
143#endif
144
145
146    return 0;
147}
148
149
150#if CFG_PCI
151static uint64_t parse_hex(const char *num)
152{
153    uint64_t x = 0;
154    unsigned int digit;
155
156    if ((*num == '0') && (*(num+1) == 'x')) num += 2;
157
158    while (*num) {
159        if ((*num >= '0') && (*num <= '9')) {
160            digit = *num - '0';
161            }
162        else if ((*num >= 'A') && (*num <= 'F')) {
163            digit = 10 + *num - 'A';
164            }
165        else if ((*num >= 'a') && (*num <= 'f')) {
166            digit = 10 + *num - 'a';
167            }
168        else {
169            break;
170            }
171        x *= 16;
172        x += digit;
173        num++;
174        }
175
176    return x;
177}
178
179static int ui_cmd_map_pci(ui_cmdline_t *cmd,int argc,char *argv[])
180{
181    unsigned long offset, size;
182    uint64_t paddr;
183    int l2ca, endian;
184    int enable;
185    int result;
186
187    enable = !cmd_sw_isset(cmd, "-off");
188    if (enable) {
189	offset = parse_hex(cmd_getarg(cmd, 0));
190	size = parse_hex(cmd_getarg(cmd, 1));
191	paddr = parse_hex(cmd_getarg(cmd, 2));
192	l2ca = cmd_sw_isset(cmd,"-l2ca");
193	endian = cmd_sw_isset(cmd, "-matchbits");
194	result = pci_map_window(paddr, offset, size, l2ca, endian);
195	}
196    else {
197	offset = parse_hex(cmd_getarg(cmd, 0));
198	size = parse_hex(cmd_getarg(cmd, 1));
199	result = pci_unmap_window(offset, size);
200	}
201
202    return result;
203}
204#endif
205
206
207#if CFG_VGACONSOLE
208static int ui_cmd_vgainit(ui_cmdline_t *cmd,int argc,char *argv[])
209{
210    int res;
211
212    res = vga_biosinit();
213
214    xprintf("vgaraw_init returns %d\n",res);
215
216    return 0;
217}
218
219static int ui_cmd_vgadump(ui_cmdline_t *cmd,int argc,char *argv[])
220{
221    char *x;
222
223    x = cmd_getarg(cmd,0);
224    if (!x) x = "";
225
226    vgaraw_dump(x);
227
228    return 0;
229}
230#endif
231
232
233int ui_init_cpldcmds(void)
234{
235
236    cmd_addcmd("write cpld",
237	       ui_cmd_writecpld,
238	       NULL,
239	       "Write bytes to the cpld",
240	       "write cpld",
241	       "");
242
243    cmd_addcmd("read cpld",
244	       ui_cmd_readcpld,
245	       NULL,
246	       "Read bytes from the cpld",
247	       "read cpld",
248	       "");
249
250    cmd_addcmd("burstw cpld",
251	       ui_cmd_burstwcpld,
252	       NULL,
253	       "Write to the cpld in 8-bit BURST MODE",
254	       "burstw cpld",
255	       "");
256
257    cmd_addcmd("burstr cpld",
258	       ui_cmd_burstrcpld,
259	       NULL,
260	       "Read from the cpld in 8-bit BURST MODE",
261	       "burstr cpld",
262	       "");
263
264    cmd_addcmd("config flash",
265	       ui_cmd_config_flash,
266	       NULL,
267	       "Configure width and burst mode for the Intel flash.",
268	       "config flash [-n|-w] [-b|-o]",
269	       "-n;switch flash1 to 8-bit mode|"
270	       "-w;switch flash1 to 16-bit mode|"
271	       "-b;burst on|"
272	       "-o;burst off");
273    return 0;
274}
275
276
277/* NORMAL WRITE to the cpld
278 * Write 8'b01010101 to address 8'b00000001 of the cpld
279 */
280static int ui_cmd_writecpld(ui_cmdline_t *cmd,int argc,char *argv[])
281{
282    /* Make sure burst mode is DISABLED. */
283    burst_mode(CPLD_CS, 0);
284
285    xprintf ("writing 0x55 to cpld address 0x01\n");
286    *((volatile uint8_t *) PHYS_TO_K1(CPLD_PHYS+0x01)) = (uint8_t) (0x55);
287    return 0;
288}
289
290
291/* NORMAL READ to the cpld
292 * The cpld is programmed to output the current cpld SUM if address 0x00 is
293 * read.  However, if any other address is read, then the cpld will output
294 * 5'b00000 concatenated with the lowest three address bits.
295 * ie.
296 * reading address 0xFF will return 0x07.
297 * reading address 0x4A will return 0x02.
298 * reading address 0x09 will return 0x01.
299 */
300static int ui_cmd_readcpld(ui_cmdline_t *cmd,int argc,char *argv[])
301{
302    uint8_t data;
303
304    /* make sure burst mode is DISABLED. */
305    burst_mode(CPLD_CS, 0);
306
307    data = *((volatile uint8_t *) PHYS_TO_K1(CPLD_PHYS+0xFC));
308    xprintf ("CPLD address 0xFC contains 0x%2X\n", data);
309    xprintf ("This value should be 0x04\n");
310    data = *((volatile uint8_t *) PHYS_TO_K1(CPLD_PHYS));
311    xprintf ("CPLD address 0x00 contains 0x%2X\n", data);
312
313    return 0;
314}
315
316
317/* BURST WRITE to the cpld
318 * Maximum burst size (without doing a UAC store) to cpld is 8 bytes.
319 * byte1: 0x01
320 * byte2: 0x02
321 * byte3: 0x04
322 * byte4: 0x08
323 * byte5: 0x10
324 * byte6: 0x20
325 * byte7: 0x40
326 * byte8: 0x80
327 * To do the burst, write the 64-bit value 0x8040201008040201 to the cpld.
328 * At the end of the burst, the cpld SUM register should contain 0xFF.
329 */
330static int ui_cmd_burstwcpld(ui_cmdline_t *cmd,int argc,char *argv[])
331{
332    /* Enable burst mode. */
333    burst_mode(CPLD_CS, 1);
334
335    xprintf("burst writing 8 bytes (0x8040201008040201) to cpld address 0x00\n");
336    *((volatile uint64_t *) PHYS_TO_K1(CPLD_PHYS)) = (uint64_t) (0x8040201008040201ULL);
337
338    return 0;
339}
340
341
342/* BURST READ to the cpld
343 * Burst reading the cpld at address 0x00 should return
344 * 0x07060504030201 concatenated with the cpld SUM[7:0]
345 */
346static int ui_cmd_burstrcpld(ui_cmdline_t *cmd,int argc,char *argv[])
347{
348    uint64_t data;
349
350    /* Enable burst mode */
351    burst_mode(CPLD_CS, 1);
352
353    data = *((volatile uint64_t *) PHYS_TO_K1(CPLD_PHYS));
354    xprintf ("Address 0x00 of cpld contains (by burst reading) 0x%16X\n", data);
355    xprintf ("This value should be 0x07060504030201FF if a burst write was just executed\n");
356
357    return 0;
358}
359
360static int ui_cmd_config_flash(ui_cmdline_t *cmd,int argc,char *argv[])
361{
362    uint64_t gpio_data;
363    unsigned int cs;
364    int flash_16bit = 0;
365    int burst_on = 0;
366
367    /* Burst and 16-bit modes make sense only for the Intel flash; the
368       alternative "flash" is a PromICE connector.  Do not change mode
369       while running from that flash, and do not attempt to update the
370       flash except in 8-bit, non-burst mode (the default). */
371
372    /* Boot flash selection is at pin 9 on GPIO; refer to lausanne.h */
373    gpio_data = SBREADCSR(A_GPIO_READ);
374    cs = (gpio_data & _SB_MAKEMASK1(GPIO_BOOT_SELECT)) ?
375	  BOOTROM_CS : ALT_BOOTROM_CS;
376
377    if (cmd_sw_isset(cmd,"-w")) {
378	/*switch to 16-bit mode*/
379	flash_16bit = 1;
380	}
381    else if (cmd_sw_isset(cmd,"-n")) {
382	/*switch to 8-bit mode*/
383	flash_16bit = 0;
384	}
385    intel_flash_data_width_mode(cs, flash_16bit);
386
387    if (cmd_sw_isset(cmd,"-b")) {
388	burst_on = 1;
389	}
390    else if (cmd_sw_isset(cmd,"-o")) {
391	burst_on = 0;
392	}
393    burst_mode(cs, burst_on);
394
395    return 0;
396
397}
398
399
400/*  *********************************************************************
401    *  Utilities
402    ********************************************************************* */
403
404static int intel_flash_data_width_mode(unsigned int cs, int flash_16bit)
405{
406    uint64_t gpio_direction;
407    uint64_t io_ext_cfg;
408
409    gpio_direction = SBREADCSR(A_GPIO_DIRECTION);
410
411    io_ext_cfg = SBREADCSR(A_IO_EXT_CS_BASE(cs));
412    io_ext_cfg &= ~M_IO_WIDTH_SEL;
413
414    if (flash_16bit) {
415	gpio_direction |= _SB_MAKEMASK1(GPIO_FLASH_BYTE_EN);
416	SBWRITECSR(A_GPIO_DIRECTION,gpio_direction);
417
418	if (DEBUG_CS) xprintf("FLASH CS %d: 16-BIT MODE\n", cs);
419	SBWRITECSR(A_GPIO_PIN_SET,_SB_MAKEMASK1(GPIO_FLASH_BYTE_EN));
420
421	/* GENBUS CS: mux'ed and 2 bytes wide */
422	io_ext_cfg |= V_IO_WIDTH_SEL(K_IO_WIDTH_SEL_2);
423	io_ext_cfg &= ~M_IO_NONMUX;   /* make sure we're mux'ed!! */
424	SBWRITECSR(A_IO_EXT_CS_BASE(cs),io_ext_cfg);
425	}
426    else {  /* 8 bit flash */
427	gpio_direction &= ~_SB_MAKEMASK1(GPIO_FLASH_BYTE_EN);  /* XXX eh?? */
428	SBWRITECSR(A_GPIO_DIRECTION,gpio_direction);
429
430	if (DEBUG_CS) xprintf("FLASH CS %d: 8-BIT MODE\n", cs);
431	SBWRITECSR(A_GPIO_PIN_CLR,_SB_MAKEMASK1(GPIO_FLASH_BYTE_EN));
432
433	/* GENBUS CS: nonmux'ed and 1 byte wide */
434	io_ext_cfg |= M_IO_NONMUX | V_IO_WIDTH_SEL(K_IO_WIDTH_SEL_1);
435	SBWRITECSR(A_IO_EXT_CS_BASE(cs),io_ext_cfg);
436	}
437    return 0;
438}
439
440static int burst_mode(unsigned int cs, int burst_on)
441{
442    uint64_t io_ext_cfg;
443
444    /*GENBUS CS */
445    io_ext_cfg = SBREADCSR(A_IO_EXT_CS_BASE(cs));
446
447    if (burst_on) {
448	io_ext_cfg |= M_IO_BURST_EN;
449	SBWRITECSR(A_IO_EXT_CS_BASE(cs), io_ext_cfg);
450	if (DEBUG_CS) xprintf("FLASH CS %d: BURST ON\n",cs);
451	}
452    else { /*burst off*/
453	io_ext_cfg &= ~M_IO_BURST_EN;
454	SBWRITECSR(A_IO_EXT_CS_BASE(cs),io_ext_cfg);
455	if (DEBUG_CS) xprintf("FLASH CS %d: BURST OFF\n",cs);
456	}
457
458    return 0;
459}
460