Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / u-boot / board / mpl / pati / cmd_pati.c
1 /*
2  * (C) Copyright 2001
3  * Denis Peter, MPL AG Switzerland, d.peter@mpl.ch
4  *
5  * SPDX-License-Identifier:     GPL-2.0+
6  *
7  * Adapted for PATI
8  */
9
10 #include <common.h>
11 #include <command.h>
12 #define PLX9056_LOC
13 #include "plx9056.h"
14 #include "pati.h"
15 #include "pci_eeprom.h"
16
17 extern void show_pld_regs(void);
18 extern int do_mplcommon(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
19
20 extern void user_led0(int led_on);
21 extern void user_led1(int led_on);
22
23 /* ------------------------------------------------------------------------- */
24 #if defined(CONFIG_SYS_PCI_CON_DEVICE)
25 extern void pci_con_disc(void);
26 extern void pci_con_connect(void);
27 #endif
28
29 /******************************************************************************
30  * Eeprom Support
31  ******************************************************************************/
32 unsigned long get32(unsigned long addr)
33 {
34         unsigned long *p=(unsigned long *)addr;
35         return *p;
36 }
37
38 void set32(unsigned long addr,unsigned long data)
39 {
40         unsigned long *p=(unsigned long *)addr;
41         *p=data;
42 }
43
44 #define PCICFG_GET_REG(x)       (get32((x) + PCI_CONFIG_BASE))
45 #define PCICFG_SET_REG(x,y)     (set32((x) + PCI_CONFIG_BASE,(y)))
46
47
48 /******************************************************************************
49  * reload_pci_eeprom
50  ******************************************************************************/
51
52 static void reload_pci_eeprom(void)
53 {
54         unsigned long reg;
55         /* Set Bit 29 and clear it again */
56         reg=PCICFG_GET_REG(PCI9056_EEPROM_CTRL_STAT);
57         udelay(1);
58         /* set it*/
59         reg|=(1<<29);
60         PCICFG_SET_REG(PCI9056_EEPROM_CTRL_STAT,reg);
61         /* EECLK @ 33MHz = 125kHz
62          * -> extra long load = 32 * 16bit = 512Bit @ 125kHz = 4.1msec
63          * use 20msec
64          */
65         udelay(20000); /* wait 20ms */
66         reg &= ~(1<<29); /* set it low */
67         PCICFG_SET_REG(PCI9056_EEPROM_CTRL_STAT,reg);
68         udelay(1); /* wait some time */
69 }
70
71 /******************************************************************************
72  * clock_pci_eeprom
73  ******************************************************************************/
74
75 static void clock_pci_eeprom(void)
76 {
77         unsigned long reg;
78         /* clock is low, data is valid */
79         reg=PCICFG_GET_REG(PCI9056_EEPROM_CTRL_STAT);
80         udelay(1);
81         /* set clck high */
82         reg|=(1<<24);
83         PCICFG_SET_REG(PCI9056_EEPROM_CTRL_STAT,reg);
84         udelay(1); /* wait some time */
85         reg &= ~(1<<24); /* set clock low */
86         PCICFG_SET_REG(PCI9056_EEPROM_CTRL_STAT,reg);
87         udelay(1); /* wait some time */
88 }
89
90 /******************************************************************************
91  * send_pci_eeprom_cmd
92  ******************************************************************************/
93 static void send_pci_eeprom_cmd(unsigned long cmd, unsigned char len)
94 {
95         unsigned long reg;
96         int i;
97         reg=PCICFG_GET_REG(PCI9056_EEPROM_CTRL_STAT);
98         /* Clear all EEPROM bits */
99         reg &= ~(0xF << 24);
100         /* Toggle EEPROM's Chip select to get it out of Shift Register Mode */
101         PCICFG_SET_REG(PCI9056_EEPROM_CTRL_STAT,reg);
102         udelay(1); /* wait some time */
103         /* Enable EEPROM Chip Select */
104         reg |= (1 << 25);
105         PCICFG_SET_REG(PCI9056_EEPROM_CTRL_STAT,reg);
106         /* Send EEPROM command - one bit at a time */
107         for (i = (int)(len-1); i >= 0; i--) {
108                 /* Check if current bit is 0 or 1 */
109                 if (cmd & (1 << i))
110                         PCICFG_SET_REG(PCI9056_EEPROM_CTRL_STAT,(reg | (1<<26)));
111                 else
112                         PCICFG_SET_REG(PCI9056_EEPROM_CTRL_STAT,reg);
113                 clock_pci_eeprom();
114         }
115 }
116
117 /******************************************************************************
118  * write_pci_eeprom_offs
119  ******************************************************************************/
120 static void write_pci_eeprom_offs(unsigned short offset, unsigned short value)
121 {
122         unsigned long reg;
123         int bitpos, cmdshft, cmdlen, timeout;
124         /* we're using the Eeprom 93CS66 */
125         cmdshft  = 2;
126         cmdlen = EE66_CMD_LEN;
127         /* Send Write_Enable command to EEPROM */
128         send_pci_eeprom_cmd((EE_WREN << cmdshft),cmdlen);
129         /* Send EEPROM Write command and offset to EEPROM */
130         send_pci_eeprom_cmd((EE_WRITE << cmdshft) | (offset / 2),cmdlen);
131         reg=PCICFG_GET_REG(PCI9056_EEPROM_CTRL_STAT);
132         /* Clear all EEPROM bits */
133         reg &= ~(0xF << 24);
134         /* Make sure EEDO Input is disabled for some PLX chips */
135         reg &= ~(1 << 31);
136         /* Enable EEPROM Chip Select */
137         reg |= (1 << 25);
138         /* Write 16-bit value to EEPROM - one bit at a time */
139         for (bitpos = 15; bitpos >= 0; bitpos--) {
140                 /* Get bit value and shift into result */
141                 if (value & (1 << bitpos))
142                         PCICFG_SET_REG(PCI9056_EEPROM_CTRL_STAT,(reg | (1<<26)));
143                 else
144                         PCICFG_SET_REG(PCI9056_EEPROM_CTRL_STAT,reg );
145                 clock_pci_eeprom();
146         } /* for */
147         /* Deselect Chip */
148         PCICFG_SET_REG(PCI9056_EEPROM_CTRL_STAT,reg & ~(1 << 25));
149         /* Re-select Chip */
150         PCICFG_SET_REG(PCI9056_EEPROM_CTRL_STAT,reg | (1 << 25));
151         /* A small delay is needed to let EEPROM complete */
152         timeout = 0;
153         do {
154                 udelay(10);
155                 reg=PCICFG_GET_REG(PCI9056_EEPROM_CTRL_STAT);
156                 timeout++;
157         } while (((reg & (1 << 27)) == 0) && timeout < 20000);
158         /* Send Write_Disable command to EEPROM */
159         send_pci_eeprom_cmd((EE_WDS << cmdshft),cmdlen);
160         /* Clear Chip Select and all other EEPROM bits */
161         PCICFG_SET_REG(PCI9056_EEPROM_CTRL_STAT,reg & ~(0xF << 24));
162 }
163
164
165 /******************************************************************************
166  * read_pci_eeprom_offs
167  ******************************************************************************/
168 static void read_pci_eeprom_offs(unsigned short offset, unsigned short *pvalue)
169 {
170         unsigned long reg;
171         int bitpos, cmdshft, cmdlen;
172         /* we're using the Eeprom 93CS66 */
173         cmdshft  = 2;
174         cmdlen = EE66_CMD_LEN;
175         /* Send EEPROM read command and offset to EEPROM */
176         send_pci_eeprom_cmd((EE_READ << cmdshft) | (offset / 2),cmdlen);
177         /* Set EEPROM write output bit */
178         reg=PCICFG_GET_REG(PCI9056_EEPROM_CTRL_STAT);
179         /* Set EEDO Input enable */
180         reg |= (1 << 31);
181         PCICFG_SET_REG(PCI9056_EEPROM_CTRL_STAT,reg | (1 << 26));
182         /* Get 16-bit value from EEPROM - one bit at a time */
183         for (bitpos = 0; bitpos < 16; bitpos++) {
184                 clock_pci_eeprom();
185                 udelay(10);
186                 reg=PCICFG_GET_REG(PCI9056_EEPROM_CTRL_STAT);
187                 /* Get bit value and shift into result */
188                 if (reg & (1 << 27))
189                         *pvalue = (unsigned short)((*pvalue << 1) | 1);
190                 else
191                         *pvalue = (unsigned short)(*pvalue << 1);
192         }
193         /* Clear EEDO Input enable */
194         reg &= ~(1 << 31);
195         /* Clear Chip Select and all other EEPROM bits */
196         PCICFG_SET_REG(PCI9056_EEPROM_CTRL_STAT,reg & ~(0xF << 24));
197 }
198
199
200 /******************************************************************************
201  * EEPROM read/writes
202 ******************************************************************************/
203
204 #undef EEPROM_DBG
205 static int pati_pci_eeprom_erase(void)
206 {
207         int i;
208         printf("Erasing EEPROM ");
209         for( i=0; i < PATI_EEPROM_LAST_OFFSET; i+=2) {
210                 write_pci_eeprom_offs(i,0xffff);
211                 if((i%0x10))
212                         printf(".");
213         }
214         printf("\nDone\n");
215         return 0;
216 }
217
218 static int pati_pci_eeprom_prg(void)
219 {
220         int i;
221         i=0;
222         printf("Programming EEPROM ");
223         while(pati_eeprom[i].offset<0xffff) {
224                 write_pci_eeprom_offs(pati_eeprom[i].offset,pati_eeprom[i].value);
225                 #ifdef EEPROM_DBG
226                 printf("0x%04X: 0x%04X\n",pati_eeprom[i].offset, pati_eeprom[i].value);
227                 #else
228                 if((i%0x10))
229                         printf(".");
230                 #endif
231                 i++;
232         }
233         printf("\nDone\n");
234         return 0;
235 }
236
237 static int pati_pci_eeprom_write(unsigned short offset, unsigned long addr, unsigned short size)
238 {
239         int i;
240         unsigned short value;
241         unsigned short *buffer =(unsigned short *)addr;
242         if((offset + size) > PATI_EEPROM_LAST_OFFSET) {
243                 size = PATI_EEPROM_LAST_OFFSET - offset;
244         }
245         printf("Write To EEPROM from 0x%lX to 0x%X 0x%X words\n", addr, offset, size/2);
246         for( i = offset; i< (offset + size); i+=2) {
247                 value = *buffer++;
248                 write_pci_eeprom_offs(i,value);
249                 #ifdef EEPROM_DBG
250                 printf("0x%04X: 0x%04X\n",i, value);
251                 #else
252                 if((i%0x10))
253                         printf(".");
254                 #endif
255         }
256         printf("\nDone\n");
257         return 0;
258 }
259
260 static int pati_pci_eeprom_read(unsigned short offset, unsigned long addr, unsigned short size)
261 {
262         int i;
263         unsigned short value = 0;
264         unsigned short *buffer =(unsigned short *)addr;
265         if((offset + size) > PATI_EEPROM_LAST_OFFSET) {
266                 size = PATI_EEPROM_LAST_OFFSET - offset;
267         }
268         printf("Read from EEPROM from 0x%X to 0x%lX 0x%X words\n", offset, addr, size/2);
269         for( i = offset; i< (offset + size); i+=2) {
270                 read_pci_eeprom_offs(i,&value);
271                 *buffer++=value;
272                 #ifdef EEPROM_DBG
273                 printf("0x%04X: 0x%04X\n",i, value);
274                 #else
275                 if((i%0x10))
276                         printf(".");
277                 #endif
278         }
279         printf("\nDone\n");
280         return 0;
281 }
282
283 /******************************************************************************
284  * PCI Bridge Registers Dump
285 *******************************************************************************/
286 static void display_pci_regs(void)
287 {
288         printf(" PCI9056_SPACE0_RANGE     %08lX\n",PCICFG_GET_REG(PCI9056_SPACE0_RANGE));
289         printf(" PCI9056_SPACE0_REMAP     %08lX\n",PCICFG_GET_REG(PCI9056_SPACE0_REMAP));
290         printf(" PCI9056_LOCAL_DMA_ARBIT  %08lX\n",PCICFG_GET_REG(PCI9056_LOCAL_DMA_ARBIT));
291         printf(" PCI9056_ENDIAN_DESC      %08lX\n",PCICFG_GET_REG(PCI9056_ENDIAN_DESC));
292         printf(" PCI9056_EXP_ROM_RANGE    %08lX\n",PCICFG_GET_REG(PCI9056_EXP_ROM_RANGE));
293         printf(" PCI9056_EXP_ROM_REMAP    %08lX\n",PCICFG_GET_REG(PCI9056_EXP_ROM_REMAP));
294         printf(" PCI9056_SPACE0_ROM_DESC  %08lX\n",PCICFG_GET_REG(PCI9056_SPACE0_ROM_DESC));
295         printf(" PCI9056_DM_RANGE         %08lX\n",PCICFG_GET_REG(PCI9056_DM_RANGE));
296         printf(" PCI9056_DM_MEM_BASE      %08lX\n",PCICFG_GET_REG(PCI9056_DM_MEM_BASE));
297         printf(" PCI9056_DM_IO_BASE       %08lX\n",PCICFG_GET_REG(PCI9056_DM_IO_BASE));
298         printf(" PCI9056_DM_PCI_MEM_REMAP %08lX\n",PCICFG_GET_REG(PCI9056_DM_PCI_MEM_REMAP));
299         printf(" PCI9056_DM_PCI_IO_CONFIG %08lX\n",PCICFG_GET_REG(PCI9056_DM_PCI_IO_CONFIG));
300         printf(" PCI9056_SPACE1_RANGE     %08lX\n",PCICFG_GET_REG(PCI9056_SPACE1_RANGE));
301         printf(" PCI9056_SPACE1_REMAP     %08lX\n",PCICFG_GET_REG(PCI9056_SPACE1_REMAP));
302         printf(" PCI9056_SPACE1_DESC      %08lX\n",PCICFG_GET_REG(PCI9056_SPACE1_DESC));
303         printf(" PCI9056_DM_DAC           %08lX\n",PCICFG_GET_REG(PCI9056_DM_DAC));
304         printf(" PCI9056_MAILBOX0         %08lX\n",PCICFG_GET_REG(PCI9056_MAILBOX0));
305         printf(" PCI9056_MAILBOX1         %08lX\n",PCICFG_GET_REG(PCI9056_MAILBOX1));
306         printf(" PCI9056_MAILBOX2         %08lX\n",PCICFG_GET_REG(PCI9056_MAILBOX2));
307         printf(" PCI9056_MAILBOX3         %08lX\n",PCICFG_GET_REG(PCI9056_MAILBOX3));
308         printf(" PCI9056_MAILBOX4         %08lX\n",PCICFG_GET_REG(PCI9056_MAILBOX4));
309         printf(" PCI9056_MAILBOX5         %08lX\n",PCICFG_GET_REG(PCI9056_MAILBOX5));
310         printf(" PCI9056_MAILBOX6         %08lX\n",PCICFG_GET_REG(PCI9056_MAILBOX6));
311         printf(" PCI9056_MAILBOX7         %08lX\n",PCICFG_GET_REG(PCI9056_MAILBOX7));
312         printf(" PCI9056_PCI_TO_LOC_DBELL %08lX\n",PCICFG_GET_REG(PCI9056_PCI_TO_LOC_DBELL));
313         printf(" PCI9056_LOC_TO_PCI_DBELL %08lX\n",PCICFG_GET_REG(PCI9056_LOC_TO_PCI_DBELL));
314         printf(" PCI9056_INT_CTRL_STAT    %08lX\n",PCICFG_GET_REG(PCI9056_INT_CTRL_STAT));
315         printf(" PCI9056_EEPROM_CTRL_STAT %08lX\n",PCICFG_GET_REG(PCI9056_EEPROM_CTRL_STAT));
316         printf(" PCI9056_PERM_VENDOR_ID   %08lX\n",PCICFG_GET_REG(PCI9056_PERM_VENDOR_ID));
317         printf(" PCI9056_REVISION_ID      %08lX\n",PCICFG_GET_REG(PCI9056_REVISION_ID));
318         printf(" \n");
319         printf(" PCI9056_VENDOR_ID        %08lX\n",PCICFG_GET_REG(PCI9056_VENDOR_ID));
320         printf(" PCI9056_COMMAND          %08lX\n",PCICFG_GET_REG(PCI9056_COMMAND));
321         printf(" PCI9056_REVISION         %08lX\n",PCICFG_GET_REG(PCI9056_REVISION));
322         printf(" PCI9056_CACHE_SIZE       %08lX\n",PCICFG_GET_REG(PCI9056_CACHE_SIZE));
323         printf(" PCI9056_RTR_BASE         %08lX\n",PCICFG_GET_REG(PCI9056_RTR_BASE));
324         printf(" PCI9056_RTR_IO_BASE      %08lX\n",PCICFG_GET_REG(PCI9056_RTR_IO_BASE));
325         printf(" PCI9056_LOCAL_BASE0      %08lX\n",PCICFG_GET_REG(PCI9056_LOCAL_BASE0));
326         printf(" PCI9056_LOCAL_BASE1      %08lX\n",PCICFG_GET_REG(PCI9056_LOCAL_BASE1));
327         printf(" PCI9056_UNUSED_BASE1     %08lX\n",PCICFG_GET_REG(PCI9056_UNUSED_BASE1));
328         printf(" PCI9056_UNUSED_BASE2     %08lX\n",PCICFG_GET_REG(PCI9056_UNUSED_BASE2));
329         printf(" PCI9056_CIS_PTR          %08lX\n",PCICFG_GET_REG(PCI9056_CIS_PTR));
330         printf(" PCI9056_SUB_ID           %08lX\n",PCICFG_GET_REG(PCI9056_SUB_ID));
331         printf(" PCI9056_EXP_ROM_BASE     %08lX\n",PCICFG_GET_REG(PCI9056_EXP_ROM_BASE));
332         printf(" PCI9056_CAP_PTR          %08lX\n",PCICFG_GET_REG(PCI9056_CAP_PTR));
333         printf(" PCI9056_INT_LINE         %08lX\n",PCICFG_GET_REG(PCI9056_INT_LINE));
334         printf(" PCI9056_PM_CAP_ID        %08lX\n",PCICFG_GET_REG(PCI9056_PM_CAP_ID));
335         printf(" PCI9056_PM_CSR           %08lX\n",PCICFG_GET_REG(PCI9056_PM_CSR));
336         printf(" PCI9056_HS_CAP_ID        %08lX\n",PCICFG_GET_REG(PCI9056_HS_CAP_ID));
337         printf(" PCI9056_VPD_CAP_ID       %08lX\n",PCICFG_GET_REG(PCI9056_VPD_CAP_ID));
338         printf(" PCI9056_VPD_DATA         %08lX\n",PCICFG_GET_REG(PCI9056_VPD_DATA));
339 }
340
341
342 int do_pati(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
343 {
344         if (strcmp(argv[1], "info") == 0)
345         {
346                 show_pld_regs();
347                 return 0;
348         }
349         if (strcmp(argv[1], "pci") == 0)
350         {
351                 display_pci_regs();
352                 return 0;
353         }
354         if (strcmp(argv[1], "led") == 0)
355         {
356                 int led_nr,led_on;
357                 led_nr = (int)simple_strtoul(argv[2], NULL, 10);
358                 led_on = (int)simple_strtoul(argv[3], NULL, 10);
359                 if(!led_nr)
360                         user_led0(led_on);
361                 else
362                         user_led1(led_on);
363                 return 0;
364         }
365 #if defined(CONFIG_SYS_PCI_CON_DEVICE)
366         if (strcmp(argv[1], "con") == 0) {
367                 pci_con_connect();
368                 return 0;
369         }
370         if (strcmp(argv[1], "disc") == 0) {
371                 pci_con_disc();
372                 return 0;
373         }
374 #endif
375         if (strcmp(argv[1], "eeprom") == 0) {
376                 unsigned long addr;
377                 int size, offset;
378                 offset = 0;
379                 size = PATI_EEPROM_LAST_OFFSET;
380                 if(argc>2) {
381                         if(argc>3) {
382                                 addr = simple_strtoul(argv[3], NULL, 16);
383                                 if(argc>4)
384                                         offset = (int) simple_strtoul(argv[4], NULL, 16);
385                                 if(argc>5)
386                                         size = (int) simple_strtoul(argv[5], NULL, 16);
387                                 if (strcmp(argv[2], "read") == 0) {
388                                         return (pati_pci_eeprom_read(offset, addr, size));
389                                 }
390                                 if (strcmp(argv[2], "write") == 0) {
391                                         return (pati_pci_eeprom_write(offset, addr, size));
392                                 }
393                         }
394                         if (strcmp(argv[2], "prg") == 0) {
395                                 return (pati_pci_eeprom_prg());
396                         }
397                         if (strcmp(argv[2], "era") == 0) {
398                                 return (pati_pci_eeprom_erase());
399                         }
400                         if (strcmp(argv[2], "reload") == 0) {
401                                 reload_pci_eeprom();
402                                 return 0;
403                         }
404
405
406                 }
407         }
408
409         return (do_mplcommon(cmdtp, flag, argc, argv));
410 }
411
412 U_BOOT_CMD(
413         pati,   8,      1,      do_pati,
414         "PATI specific Cmds",
415         "info - displays board information\n"
416         "pati pci  - displays PCI registers\n"
417         "pati led <nr> <on> \n"
418         "          - switch LED <nr> <on>\n"
419         "pati flash mem [SrcAddr]\n"
420         "          - updates U-Boot with image in memory\n"
421         "pati eeprom <cmd> - PCI EEPROM sub-system\n"
422         "    read <addr> <offset> <size>\n"
423         "          - read PCI EEPROM to <addr> from <offset> <size> words\n"
424         "    write <addr> <offset> <size>\n"
425         "          - write PCI EEPROM from <addr> to <offset> <size> words\n"
426         "    prg   - programm PCI EEPROM with default values\n"
427         "    era   - erase PCI EEPROM (write all word to 0xffff)\n"
428         "    reload- Reload PCI Bridge with EEPROM Values\n"
429         "    NOTE: <addr> must start on word boundary\n"
430         "          <offset> and <size> must be even byte values"
431 );
432
433 /* ------------------------------------------------------------------------- */