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