]> git.kernelconcepts.de Git - karo-tx-redboot.git/blob - packages/hal/arm/xscale/triton270/v2_0/src/triton270_misc.c
RedBoot TX53 Release 2012-02-15
[karo-tx-redboot.git] / packages / hal / arm / xscale / triton270 / v2_0 / src / triton270_misc.c
1 //==========================================================================
2 //
3 //      triton270_misc.c
4 //
5 //      HAL misc board support code for XScale TRITON270
6 //
7 //==========================================================================
8 //#####ECOSGPLCOPYRIGHTBEGIN####
9 //## -------------------------------------------
10 //## This file is part of eCos, the Embedded Configurable Operating System.
11 //## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
12 //##
13 //## eCos is free software; you can redistribute it and/or modify it under
14 //## the terms of the GNU General Public License as published by the Free
15 //## Software Foundation; either version 2 or (at your option) any later version.
16 //##
17 //## eCos is distributed in the hope that it will be useful, but WITHOUT ANY
18 //## WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 //## FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
20 //## for more details.
21 //##
22 //## You should have received a copy of the GNU General Public License along
23 //## with eCos; if not, write to the Free Software Foundation, Inc.,
24 //## 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
25 //##
26 //## As a special exception, if other files instantiate templates or use macros
27 //## or inline functions from this file, or you compile this file and link it
28 //## with other works to produce a work based on this file, this file does not
29 //## by itself cause the resulting work to be covered by the GNU General Public
30 //## License. However the source code for this file must still be made available
31 //## in accordance with section (3) of the GNU General Public License.
32 //##
33 //## This exception does not invalidate any other reasons why a work based on
34 //## this file might be covered by the GNU General Public License.
35 //##
36 //## Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
37 //## at http://sources.redhat.com/ecos/ecos-license/
38 //## -------------------------------------------
39 //#####ECOSGPLCOPYRIGHTEND####
40 //==========================================================================
41 //#####DESCRIPTIONBEGIN####
42 //
43 // Author(s):    msalter, usteinkohl
44 // Contributors: msalter, usteinkohl
45 // Date:         20th August 2004 (last modification)
46 // Purpose:      HAL board support
47 // Description:  Implementations of HAL board interfaces
48 //
49 //####DESCRIPTIONEND####
50 //
51 //========================================================================*/
52 #include <redboot.h>
53 #include <flash_config.h>
54
55 #include <pkgconf/hal.h>
56 #include <pkgconf/system.h>
57 #include CYGBLD_HAL_PLATFORM_H
58 #include CYGHWR_MEMORY_LAYOUT_H
59
60 #include <cyg/infra/cyg_type.h>         // base types
61 #include <cyg/infra/cyg_trac.h>         // tracing macros
62 #include <cyg/infra/cyg_ass.h>          // assertion macros
63
64 #include <cyg/hal/hal_io.h>             // IO macros
65 #include <cyg/hal/hal_stub.h>           // Stub macros
66 #include <cyg/hal/hal_if.h>             // calling interface API
67 #include <cyg/hal/hal_arch.h>           // Register state info
68 #include <cyg/hal/hal_diag.h>
69 #include <cyg/hal/hal_intr.h>           // Interrupt names
70 #include <cyg/hal/hal_cache.h>
71 #include <cyg/hal/hal_triton270.h>      // Hardware definitions
72 #include <cyg/hal/drv_api.h>            // CYG_ISR_HANDLED
73
74 extern int  printf(char *fmt, ...);
75
76 inline unsigned long _fu_phys_address(unsigned long _x_)
77 {
78         switch (_x_>>12) {
79         case 0x0:
80                 return _x_ + 0xa0000000;
81         case 0xa0000:
82                 return _x_ & 0xfffffff;
83         default:
84                 return _x_;
85         }
86 }
87
88 /*------------------------------------------------------------------------*/
89 /* IDE support                                                            */
90
91 void cyg_hal_plf_ide_init(void)
92 {
93 }
94
95 void coldstart(void)
96 {
97         cyg_uint32              value;
98
99         HAL_WRITE_UINT32(OSCR, 0);      // initialize os timer counter
100         HAL_WRITE_UINT32(RCNR, 0);      // initialize rtc counter
101         HAL_WRITE_UINT32(RTTR, 0x7FFF); // divide RTC to get 1hz output
102         //
103         // initialize interrupt registers
104         //
105         HAL_WRITE_UINT32(ICMR, 0);      // Pending Interrupts are masked from becoming active
106         HAL_WRITE_UINT32(ICMR2, 0);
107         HAL_WRITE_UINT32(ICLR, 0);      // Route all Interrupts to CPU IRQ (none to FIQ)
108         HAL_WRITE_UINT32(ICLR2, 0);
109         HAL_WRITE_UINT32(ICCR, 1);      // Only enabled and unmasked interrupt bring core out of idle
110
111         //
112         //  setup general purpose I/Os (specific to TRITON270 board)
113         //  must set GPSR/GPCR, then set GPDR, then set GPAFR
114         //
115         //  this is already done in the assembly code.
116
117         // clear all edge detect status bits
118         HAL_WRITE_UINT32(GEDRa, 0xffffffff);  // clear all bits
119         HAL_WRITE_UINT32(GEDRb, 0xffffffff);
120         HAL_WRITE_UINT32(GEDRc, 0xffffffff);
121         HAL_WRITE_UINT32(GEDRd, 0xffffffff);
122
123         //   setup PCMCIA timing parameters (should be optimized (usteinkohl)
124         //
125         //      this is SK3 specific
126         //
127         //      for about 200 MHz MEMCLK:
128         //              command setup:                   30 nsec
129         //              command minimum duration:       100 nsec
130         //              command hold:                    20 nsec
131
132         HAL_WRITE_UINT32(MCIO0, 0x00040286);
133         HAL_WRITE_UINT32(MCIO1, 0x00040286);
134
135         HAL_WRITE_UINT32(MCMEM0, 0x00040286);
136         HAL_WRITE_UINT32(MCMEM1, 0x00040286);
137
138         HAL_WRITE_UINT32(MCATT0, 0x00040286);
139         HAL_WRITE_UINT32(MCATT1, 0x00040286);
140
141         HAL_WRITE_UINT32(MECR, 0x3);   // set CIT and NOS
142
143         HAL_WRITE_UINT32(PWRICR, ICR_UR);                               // reset i2c_unit;
144         HAL_WRITE_UINT32(PWRICR, ICR_IUE | ICR_SCLE | ICR_GCD);
145
146         HAL_READ_UINT32(PCFR, value);
147         //value |= 0x00000040;                  // enable PI2C
148         value = value & (~0x400);               // disable voltage change sequencer
149         HAL_WRITE_UINT32(PCFR, value);
150 }
151
152 void hal_sio_print_string(char *buf)
153 {
154         cyg_uint32 value;
155
156         while(1) {
157                 HAL_READ_UINT32(STLSR, value);
158                 while(!(value & 0x40)) {
159                         HAL_READ_UINT32(STLSR, value);
160                 }
161                 value = (cyg_uint32)(*buf++) & 0xff;
162                 if (!value) {
163                         return;
164                 } else {
165                         HAL_WRITE_UINT32(STTHR, value);
166                 }
167         }
168
169 }
170
171 void unlock_flash_all(void);
172
173 void hal_hardware_init(void)
174 {
175         cyg_uint32 cken;
176         cyg_uint32 val;
177         int ind;
178
179         HAL_READ_UINT32(CKEN, cken);
180         // enable FFUART clock and BTUART clock and STUART
181         HAL_WRITE_UINT32(CKEN, cken | 0xe0);
182
183         // Let the "OS" counter run
184         coldstart();
185
186         // Set up eCos/ROM interfaces
187         hal_if_init(); //ecos, not platform, specifc.  Common to all.  Do not change.
188
189         // Enable caches
190         HAL_DCACHE_ENABLE();  //leave this
191         HAL_ICACHE_ENABLE();    //leave this
192
193         //diag_printf("CKEN register: 0x%08X\n", cken);
194
195         // check if we restart from sleep mode
196         HAL_READ_UINT32(RCSR, val);
197         //HAL_WRITE_UINT32(RCSR, 0xf);          // clear all bits
198         if (val & 0x0f) {
199                 const char *sep = " ";
200                 diag_printf("\nReset caused by:");
201                 if (val & 1) {
202                         diag_printf("%shardware reset pin", sep);
203                         sep = " + ";
204                 }
205                 if (val & 0x02) {
206                         diag_printf("%swatchdog reset", sep);
207                         sep = " + ";
208                 }
209                 if (val & 0x08) {
210                         diag_printf("%sGPIO reset\n", sep);
211                         sep = " + ";
212                 }
213                 if (val & 0x04) {
214                         diag_printf("%ssleep reset", sep);
215                         sep = " + ";
216                         HAL_READ_UINT32(PSPR, val);
217                         if (!val) {
218                                 diag_printf("\nwarning, NULL pointer detected in PSPR register\n");
219                         } else {
220                                 diag_printf("\nrestarting operating system ...\n");
221                                 asm volatile (
222                                               "mov pc, %0;"     // jump to pointer
223                                               :
224                                               : "r"(val)
225                                               );
226                         }
227                 }
228                 diag_printf("\n");
229         } else {
230                 diag_printf("\nwarning, unknown reset source !!!!\n");
231                 diag_printf("RCSR register: 0x%08X\n", val);
232         }
233
234         ind = get_clock_table_index(208);
235
236         HAL_READ_UINT32(MDREFR, val);
237         val |= 0x20000000;                              // set K0DB4
238         HAL_WRITE_UINT32(MDREFR, val);
239
240         change_core_voltage(ind);
241         change_clock(ind);
242
243         if (pclktab[ind].MDREFR_K0DB2) {
244                 HAL_READ_UINT32(MDREFR, val);                           // set K0DB2
245                 val |= 0x00004000;
246         } else {
247                 HAL_READ_UINT32(MDREFR, val);                           // reset K0DB0
248                 val &= (~0x00004000);
249         }
250         HAL_WRITE_UINT32(MDREFR, val);
251
252         if (pclktab[ind].MDREFR_K0DB4) {
253                 HAL_READ_UINT32(MDREFR, val);                           // set K0DB2
254                 val |= 0x20000000;
255         } else {
256                 HAL_READ_UINT32(MDREFR, val);                           // reset K0DB2
257                 val &= (~0x20000000);
258         }
259         HAL_WRITE_UINT32(MDREFR, val);
260 }
261
262 void enable_sdcard_power(void)
263 {
264         unsigned long value;
265
266         HAL_READ_UINT32(GAFR1c, value);                 // set alternate function of GPIO91 to 0
267         value &= 0xff3fffff;
268         HAL_WRITE_UINT32(GAFR1c, value);
269
270         HAL_READ_UINT32(GPDRc, value);                  // config GPIO91 as output
271         value |= 0x08000000;
272         HAL_WRITE_UINT32(GPDRc, value);
273
274         HAL_WRITE_UINT32(GPCRc, 0x08000000);    // clear GPIO91
275         HAL_DELAY_US(1000*1000);
276
277         HAL_WRITE_UINT32(DRCMR21, 0x00000088);  // map SDCARD receive to DMA channel No. 8
278         HAL_WRITE_UINT32(DCSR8, 0x40000000);    // set DMA channel to no descriptor fetch mode
279         HAL_WRITE_UINT32(DALGN, 0x100);                 // allow byte allinement for channel 8
280
281 #if 0   // only for Debug
282         HAL_WRITE_UINT32(GPCRa, 0x800);
283
284         HAL_READ_UINT32(GPDRa, value);
285         value |= 0x800;
286         HAL_WRITE_UINT32(GPDRa, value);
287 #endif
288
289 }
290
291 #include CYGHWR_MEMORY_LAYOUT_H
292 typedef void code_fun(void);
293 void triton270_program_new_stack(void *func)
294 {
295         register CYG_ADDRESS stack_ptr asm("sp");
296         register CYG_ADDRESS old_stack asm("r4");
297         register code_fun *new_func asm("r0");
298
299         old_stack = stack_ptr;
300
301         stack_ptr = CYGMEM_REGION_ram + CYGMEM_REGION_ram_SIZE - sizeof(CYG_ADDRESS);
302         new_func = (code_fun*)func;
303         new_func();
304
305         stack_ptr = old_stack;
306 }
307
308 #if 0
309     asm volatile (
310                   "ldr          r1,=0x00000800;" // we use GPIO23 for controlling the debug LED
311
312                   "250961:;"
313                   "ldr          r0,=0x40E00024;"        // GPCR0
314                   "str          r1,     [r0];"          // switch the LED on
315                   
316                   "ldr          r2,=0x00a00000;"        // wait some time
317                   "mov          r3,#1 ;"
318                   "998:;"
319                   "sub          r2, r2, r3;"
320                   "cmp          r2,#0;"
321                   "bne          998b;"
322
323                   "ldr          r0,=0x40E00018;"        // GPSR0
324                   "str          r1,     [r0];"          // switch the LED off
325
326                   "ldr          r2,=0x00a00000;"        // wait some time
327                   "mov          r3,#1;"
328                   "998:;"
329                   "sub          r2, r2, r3;"
330                   "cmp          r2,#0;"
331                   "bne          998b;"
332
333                   "b            250961b;"
334                   :
335                   :
336                   : "r0","r1","r2","r3"
337                   );
338 #endif
339
340 // Initialize the clock
341 static cyg_uint32  clock_period;
342
343 void hal_clock_initialize(cyg_uint32 period)
344 {
345         cyg_uint32 oier;
346
347         // Load match value
348         HAL_WRITE_UINT32(OSMR0, period);
349         clock_period = period;
350
351         // Start the counter
352         HAL_WRITE_UINT32(OSCR, 0);
353         // Clear any pending interrupt
354         HAL_WRITE_UINT32(OSSR, OSSR_TIMER0);
355         // Enable timer 0 interrupt
356         HAL_READ_UINT32(OIER, oier);
357         HAL_WRITE_UINT32(OIER, oier | OIER_TIMER0);
358
359         // Unmask timer 0 interrupt
360         HAL_INTERRUPT_UNMASK(CYGNUM_HAL_INTERRUPT_TIMER0);
361 }
362
363 // This routine is called during a clock interrupt.
364 void hal_clock_reset(cyg_uint32 vector, cyg_uint32 period)
365 {
366         cyg_uint32 oscr;
367
368         // Load new match value
369         HAL_READ_UINT32(OSCR, oscr);
370         HAL_WRITE_UINT32(OSMR0, oscr + period);
371         // Clear any pending interrupt
372         HAL_WRITE_UINT32(OSSR, OSSR_TIMER0);
373 }
374
375 // Read the current value of the clock, returning the number of hardware
376 // "ticks" that have occurred (i.e. how far away the current value is from
377 // the start)
378
379 // Note: The "contract" for this function is that the value is the number
380 // of hardware clocks that have happened since the last interrupt (i.e.
381 // when it was reset).  This value is used to measure interrupt latencies.
382 // However, since the hardware counter runs freely, this routine computes
383 // the difference between the current clock period and the number of hardware
384 // ticks left before the next timer interrupt.
385 void hal_clock_read(cyg_uint32 *pvalue)
386 {
387         int orig;
388         cyg_uint32 oscr;
389         cyg_uint32 osmr0;
390
391         HAL_DISABLE_INTERRUPTS(orig);
392         HAL_READ_UINT32(OSCR, oscr);
393         HAL_READ_UINT32(OSMR0, osmr0);
394         *pvalue = clock_period + oscr - osmr0;
395         HAL_RESTORE_INTERRUPTS(orig);
396 }
397
398 // Delay for some number of micro-seconds
399 void hal_delay_us(cyg_uint32 time)
400 {
401         cyg_uint32 val = 0;
402         cyg_uint32 ctr;
403
404         HAL_READ_UINT32(OSCR, ctr);
405         while (time-- > 0) {
406                 do {
407                         cyg_uint32 oscr;
408
409                         HAL_READ_UINT32(OSCR, oscr);
410                         if (ctr != oscr) {
411                                 // FIXME: DEFINE AND USE a global CLOCK_TICK_RATE somewhere!
412                                 // This value is WRONG for PXA270!
413                                 //val += 271267;        // 271267ps (3.6864Mhz -> 271.267ns)
414                                 val += 307692;          // 307692ps (3.25Mhz -> 307.692ns)
415                                 ++ctr;
416                         }
417                 } while (val < 1000000);
418                 val -= 1000000;
419         }
420 }
421
422 typedef cyg_uint32 cyg_ISR(cyg_uint32 vector, CYG_ADDRWORD data);
423
424 extern void cyg_interrupt_post_dsr(CYG_ADDRWORD intr_obj);
425
426 static inline cyg_uint32 hal_call_isr(cyg_uint32 vector)
427 {
428         return 0;
429 }
430
431 // Interrupt handling
432
433 // This routine is called to respond to a hardware interrupt (IRQ).  It
434 // should interrogate the hardware and return the IRQ vector number.
435 int hal_IRQ_handler(void)
436 {
437         cyg_uint32 sources, index;
438
439 #ifdef HAL_EXTENDED_IRQ_HANDLER
440         // Use platform specific IRQ handler, if defined
441         // Note: this macro should do a 'return' with the appropriate
442         // interrupt number if such an extended interrupt exists.  The
443         // assumption is that the line after the macro starts 'normal' processing.
444         HAL_EXTENDED_IRQ_HANDLER(index);
445 #endif
446
447         HAL_READ_UINT32(ICIP, sources);
448         if (sources & 0xff0000) {
449                 index = 16;
450         } else if (sources & 0xff00) {
451                 index = 8;
452         } else if (sources & 0xff) {
453                 index = 0;
454         } else {
455                 index = 24;
456         }
457         do {
458                 if ((1 << index) & sources) {
459                         if (index == CYGNUM_HAL_INTERRUPT_GPIO) {
460                                 // Special case of GPIO cascade.  Search for lowest set bit
461                                 HAL_READ_UINT32(GEDRa, sources);
462                                 index = 0;
463                                 do {
464                                         if (sources & (1 << index)) {
465                                                 return index + 32;
466                                         }
467                                         index++;
468                                 } while (index < 32);
469                                 HAL_READ_UINT32(GEDRb, sources);
470                                 index = 0;
471                                 do {
472                                         if (sources & (1 << index)) {
473                                                 return index + 64;
474                                         }
475                                         index++;
476                                 } while (index < 32);
477                                 HAL_READ_UINT32(GEDRc, sources);
478                                 index = 0;
479                                 do {
480                                         if (sources & (1 << index)) {
481                                                 return index + 96;
482                                         }
483                                         index++;
484                                 } while (index < 32);
485                                 HAL_READ_UINT32(GEDRc, sources);
486                                 index = 0;
487                                 do {
488                                         if (sources & (1 << index)) {
489                                                 return index + 128;
490                                         }
491                                         index++;
492                                 } while (index < 23); // GPIOs 96..118
493                         }
494                         return index;
495                 }
496                 index++;
497         } while (index & 7);
498
499         return CYGNUM_HAL_INTERRUPT_NONE; // This shouldn't happen!
500 }
501
502 void hal_interrupt_mask(int vector)
503 {
504         cyg_uint32 icmr;
505
506 #ifdef HAL_EXTENDED_INTERRUPT_MASK
507         // Use platform specific handling, if defined
508         // Note: this macro should do a 'return' for "extended" values of 'vector'
509         // Normal vectors are handled by code subsequent to the macro call.
510         HAL_EXTENDED_INTERRUPT_MASK(vector);
511 #endif
512         if (vector >= CYGNUM_HAL_INTERRUPT_GPIO2) {
513                 vector = CYGNUM_HAL_INTERRUPT_GPIO;
514         }
515         HAL_READ_UINT32(ICMR, icmr);
516         HAL_WRITE_UINT32(ICMR, icmr & ~(1 << vector));
517 }
518
519 void hal_interrupt_unmask(int vector)
520 {
521         cyg_uint32 icmr;
522
523 #ifdef HAL_EXTENDED_INTERRUPT_UNMASK
524         // Use platform specific handling, if defined
525         // Note: this macro should do a 'return' for "extended" values of 'vector'
526         // Normal vectors are handled by code subsequent to the macro call.
527         HAL_EXTENDED_INTERRUPT_UNMASK(vector);
528 #endif
529
530         if (vector >= CYGNUM_HAL_INTERRUPT_GPIO2) {
531                 vector = CYGNUM_HAL_INTERRUPT_GPIO;
532         }
533         HAL_READ_UINT32(ICMR, icmr);
534         HAL_WRITE_UINT32(ICMR, icmr | (1 << vector));
535 }
536
537 void hal_interrupt_acknowledge(int vector)
538 {
539         cyg_uint32 rtsr;
540
541 #if DEBUG_INT
542         diag_printf("void hal_interrupt_acknowledge(int vector) entered ...\n");
543         diag_printf("vector = %d     \n", vector);
544 #endif
545         switch (vector) {
546         case CYGNUM_HAL_INTERRUPT_ALARM:
547                 HAL_READ_UINT32(RTSR, rtsr);
548                 HAL_WRITE_UINT32(RTSR, (rtsr & ~0x2553) | 0x1);
549                 break;
550         case CYGNUM_HAL_INTERRUPT_HZ:
551                 HAL_READ_UINT32(RTSR, rtsr);
552                 HAL_WRITE_UINT32(RTSR, (rtsr & ~0x2553) | 0x2);
553                 break;
554         case CYGNUM_HAL_INTERRUPT_TIMER3:
555                 HAL_WRITE_UINT32(OSSR, 0x08);
556                 break;
557         case CYGNUM_HAL_INTERRUPT_TIMER2:
558                 HAL_WRITE_UINT32(OSSR, 0x04);
559                 break;
560         case CYGNUM_HAL_INTERRUPT_TIMER1:
561                 HAL_WRITE_UINT32(OSSR, 0x02);
562                 break;
563         case CYGNUM_HAL_INTERRUPT_TIMER0:
564                 HAL_WRITE_UINT32(OSSR, 0x01);
565                 break;
566         case CYGNUM_HAL_INTERRUPT_DMA:
567                 // user specific code here
568                 break;
569         case CYGNUM_HAL_INTERRUPT_SSP:
570                 // user specific code here
571                 break;
572         case CYGNUM_HAL_INTERRUPT_MMC:
573                 // user specific code here
574                 break;
575         case CYGNUM_HAL_INTERRUPT_FFUART:
576                 // user specific code here
577                 break;
578         case CYGNUM_HAL_INTERRUPT_BTUART:
579                 // user specific code here
580                 break;
581         case CYGNUM_HAL_INTERRUPT_STUART:
582                 // user specific code here
583                 break;
584         case CYGNUM_HAL_INTERRUPT_ICP:
585                 // user specific code here
586                 break;
587         case CYGNUM_HAL_INTERRUPT_I2S:
588                 // user specific code here
589                 break;
590         case CYGNUM_HAL_INTERRUPT_LCD:
591                 // user specific code here
592                 break;
593         case CYGNUM_HAL_INTERRUPT_AC97:
594                 // user specific code here
595                 break;
596         case CYGNUM_HAL_INTERRUPT_I2C:
597                 // user specific code here
598                 break;
599         case CYGNUM_HAL_INTERRUPT_PMU:
600                 // user specific code here
601                 break;
602         case CYGNUM_HAL_INTERRUPT_USB:
603                 // user specific code here
604                 break;
605                 // GPIO interrupts are driven by an edge detection mechanism.  This
606                 // is latching so these interrupts must be acknowledged directly.
607                 // All other interrupts simply go away when the interrupting unit
608                 // has been serviced by the ISR.
609         case CYGNUM_HAL_INTERRUPT_GPIO1:
610                 HAL_WRITE_UINT32(GEDRa, 0x2);
611                 break;
612         case CYGNUM_HAL_INTERRUPT_GPIO0:
613                 HAL_WRITE_UINT32(GEDRa, 0x1);
614                 break;
615         default:                // the rest is second level GPIO
616                 if (vector >= CYGNUM_HAL_INTERRUPT_GPIO96) {
617                         HAL_WRITE_UINT32(GEDRd, (1 << (vector - 128)));
618                 } else if (vector >= CYGNUM_HAL_INTERRUPT_GPIO64) {
619                         HAL_WRITE_UINT32(GEDRc, (1 << (vector - 96)));
620                 } else if (vector >= CYGNUM_HAL_INTERRUPT_GPIO32) {
621                         HAL_WRITE_UINT32(GEDRb, (1 << (vector - 64)));
622                 } else if (vector >= CYGNUM_HAL_INTERRUPT_GPIO2) {
623                         HAL_WRITE_UINT32(GEDRa, (1 << (vector - 32)));
624                 }
625                 break;
626         }
627         return;
628 }
629
630 void hal_interrupt_configure(int vector, int level, int up)
631 {
632 #if DEBUG_INT
633         diag_printf("void hal_interrupt_configure(int vector, int level, int up) entered ...\n");
634         diag_printf("vector = %d    level = %d      up = %d   \n", vector, level, up);
635 #endif
636 #if 0
637 #ifdef HAL_EXTENDED_INTERRUPT_CONFIGURE
638         // Use platform specific handling, if defined
639         // Note: this macro should do a 'return' for "extended" values of 'vector'
640         // Normal vectors are handled by code subsequent to the macro call.
641         HAL_EXTENDED_INTERRUPT_CONFIGURE(vector, level, up);
642 #endif
643         if (vector >= CYGNUM_HAL_INTERRUPT_GPIO64) {
644                 if (level) {
645                         if (up) {
646                                 // Enable both edges
647                                 *(unsigned long*)GRERc |= (1 << (vector - 96));
648                                 *(unsigned long*)GFERc |= (1 << (vector - 96));
649                         } else {
650                                 // Disable both edges
651                                 *(unsigned long*)GRERc &= ~(1 << (vector - 96));
652                                 *(unsigned long*)GFERc &= ~(1 << (vector - 96));
653                         }
654                 } else {
655                         // Only interested in one edge
656                         if (up) {
657                                 // Set rising edge detect and clear falling edge detect.
658                                 *(unsigned long*)GRERc |= (1 << (vector - 96));
659                                 *(unsigned long*)GFERc &= ~(1 << (vector - 96));
660                         } else {
661                                 // Set falling edge detect and clear rising edge detect.
662                                 *(unsigned long*)GFERc |= (1 << (vector - 96));
663                                 *(unsigned long*)GRERc &= ~(1 << (vector - 96));
664                         }
665                 }
666         } else if (vector >= CYGNUM_HAL_INTERRUPT_GPIO32) {
667                 if (level) {
668                         if (up) {
669                                 // Enable both edges
670                                 *(unsigned long*)GRERb |= (1 << (vector - 64));
671                                 *(unsigned long*)GFERb |= (1 << (vector - 64));
672                         } else {
673                                 // Disable both edges
674                                 *(unsigned long*)GRERb &= ~(1 << (vector - 64));
675                                 *(unsigned long*)GFERb &= ~(1 << (vector - 64));
676                         }
677                 } else {
678                         // Only interested in one edge
679                         if (up) {
680                                 // Set rising edge detect and clear falling edge detect.
681                                 *(unsigned long*)GRERb |= (1 << (vector - 64));
682                                 *(unsigned long*)GFERb &= ~(1 << (vector - 64));
683                         } else {
684                                 // Set falling edge detect and clear rising edge detect.
685                                 *(unsigned long*)GFERb |= (1 << (vector - 64));
686                                 *(unsigned long*)GRERb &= ~(1 << (vector - 64));
687                         }
688                 }
689         } else if (vector >= CYGNUM_HAL_INTERRUPT_GPIO2) {
690                 if (level) {
691                         if (up) {
692                                 // Enable both edges
693                                 *(unsigned long*)GRERa |= (1 << (vector - 32));
694                                 *(unsigned long*)GFERa |= (1 << (vector - 32));
695                         } else {
696                                 // Disable both edges
697                                 *(unsigned long*)GRERa &= ~(1 << (vector - 32));
698                                 *(unsigned long*)GFERa &= ~(1 << (vector - 32));
699                         }
700                 } else {
701                         // Only interested in one edge
702                         if (up) {
703                                 // Set rising edge detect and clear falling edge detect.
704                                 *(unsigned long*)GRERa |= (1 << (vector - 32));
705                                 *(unsigned long*)GFERa &= ~(1 << (vector - 32));
706                         } else {
707                                 // Set falling edge detect and clear rising edge detect.
708                                 *(unsigned long*)GFERa |= (1 << (vector - 32));
709                                 *(unsigned long*)GRERa &= ~(1 << (vector - 32));
710                         }
711                 }
712         } else if (vector == CYGNUM_HAL_INTERRUPT_GPIO0 || vector == CYGNUM_HAL_INTERRUPT_GPIO1) {
713                 if (level) {
714                         if (up) {
715                                 // Enable both edges
716                                 *(unsigned long*)GRERa |= (1 << (vector - 8));
717                                 *(unsigned long*)GFERa |= (1 << (vector - 8));
718                         } else {
719                                 // Disable both edges
720                                 *(unsigned long*)GRERa &= ~(1 << (vector - 8));
721                                 *(unsigned long*)GFERa &= ~(1 << (vector - 8));
722                         }
723                 } else {
724                         // Only interested in one edge
725                         if (up) {
726                                 // Set rising edge detect and clear falling edge detect.
727                                 *(unsigned long*)GRERa |= (1 << (vector - 8));
728                                 *(unsigned long*)GFERa &= ~(1 << (vector - 8));
729                         } else {
730                                 // Set falling edge detect and clear rising edge detect.
731                                 *(unsigned long*)GFERa |= (1 << (vector - 8));
732                                 *(unsigned long*)GRERa &= ~(1 << (vector - 8));
733                         }
734                 }
735         }
736 #endif
737 }
738
739 void hal_interrupt_set_level(int vector, int level)
740 {
741 }
742
743 /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
744 /* Command and code to reset the hardware by issuing the reset vector      */
745 /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
746 void cyg_hal_xscale_soft_reset(CYG_ADDRESS entry)
747 {
748         unsigned long value;
749
750         diag_printf("\nDoing software reset now");
751
752         // clear reset status
753         HAL_WRITE_UINT32(RCSR, 0x0f);
754
755         HAL_READ_UINT32(OSCR, value);
756         value += 325000;
757         HAL_WRITE_UINT32(OSMR3, value);
758         HAL_WRITE_UINT32(OWER, 1);
759         while (1) { // wait here for watchdog reset
760                 diag_printf(".");
761                 HAL_DELAY_US(10 * 1000);
762         }
763 }
764
765 void do_triton_reset(int argc, char *argv[])
766 {
767         HAL_PLATFORM_RESET();
768 }
769
770 RedBoot_cmd("reset",
771             "Reset the board/hardware",
772             "",
773             do_triton_reset
774             );
775
776 #ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
777 /*------------------------------------------------------------------------*/
778 //  HW Debug support
779
780 static inline void set_ibcr0(unsigned x)
781 {
782         asm volatile ("mcr p15,0,%0,c14,c8,0" : : "r"(x));
783 }
784
785 static inline unsigned get_ibcr0(void)
786 {
787         unsigned x;
788         asm volatile ("mrc p15,0,%0,c14,c8,0" : "=r"(x) :);
789         return x;
790 }
791
792 static inline void set_ibcr1(unsigned x)
793 {
794         asm volatile ("mcr p15,0,%0,c14,c9,0" : : "r"(x));
795 }
796
797 static inline unsigned get_ibcr1(void)
798 {
799         unsigned x;
800         asm volatile ("mrc p15,0,%0,c14,c9,0" : "=r"(x) :);
801         return x;
802 }
803
804 static inline void set_dbr0(unsigned x)
805 {
806         asm volatile ("mcr p15,0,%0,c14,c0,0" : : "r"(x));
807 }
808
809 static inline unsigned get_dbr0(void)
810 {
811         unsigned x;
812         asm volatile ("mrc p15,0,%0,c14,c0,0" : "=r"(x) :);
813         return x;
814 }
815
816 static inline void set_dbr1(unsigned x)
817 {
818         asm volatile ("mcr p15,0,%0,c14,c3,0" : : "r"(x));
819 }
820
821 static inline unsigned get_dbr1(void)
822 {
823         unsigned x;
824         asm volatile ("mrc p15,0,%0,c14,c3,0" : "=r"(x) :);
825         return x;
826 }
827
828 static inline void set_dbcon(unsigned x)
829 {
830         asm volatile ("mcr p15,0,%0,c14,c4,0" : : "r"(x));
831 }
832
833 static inline unsigned get_dbcon(void)
834 {
835         unsigned x;
836         asm volatile ("mrc p15,0,%0,c14,c4,0" : "=r"(x) :);
837         return x;
838 }
839
840 static inline void set_dcsr(unsigned x)
841 {
842         asm volatile ("mcr p14,0,%0,c10,c0,0" : : "r"(x));
843 }
844
845 static inline unsigned get_dcsr(void)
846 {
847         unsigned x;
848         asm volatile ("mrc p14,0,%0,c10,c0,0" : "=r"(x) :);
849         return x;
850 }
851
852 int cyg_hal_plf_hw_breakpoint(int setflag, void *vaddr, int len)
853 {
854         unsigned int addr = (unsigned)vaddr;
855
856         if (setflag) {
857                 if (!(get_ibcr0() & 1))
858                         set_ibcr0(addr | 1);
859                 else if (!(get_ibcr1() & 1))
860                         set_ibcr1(addr | 1);
861                 else
862                         return -1;
863         } else {
864                 unsigned x = (addr | 1);
865                 if (get_ibcr0() == x)
866                         set_ibcr0(0);
867                 else if (get_ibcr0() == x)
868                         set_ibcr1(0);
869                 else
870                         return -1;
871         }
872         return 0;
873 }
874
875 int cyg_hal_plf_hw_watchpoint(int setflag, void *vaddr, int len, int type)
876 {
877         unsigned int mask, bit_nr, mode, addr = (unsigned)vaddr;
878         unsigned dbcon = get_dbcon();
879
880         mask = 0x80000000;
881         bit_nr = 31;
882         while (bit_nr) {
883                 if (len & mask)
884                         break;
885                 bit_nr--;
886                 mask >>= 1;
887         }
888         mask = ~(0xffffffff << bit_nr);
889
890         if (setflag) {
891                 /* set a watchpoint */
892                 if (type == 2)
893                         mode = 1; // break on write
894                 else if (type == 3)
895                         mode = 3; // break on read
896                 else if (type == 4)
897                         mode = 2; // break on any access
898                 else
899                         return 1;
900
901                 if (!(dbcon & 3)) {
902                         set_dbr0(addr);
903                         set_dbr1(mask);
904                         set_dbcon(dbcon | mode | 0x100);
905                 } else
906                         return 1;
907         } else {
908                 /* clear a watchpoint */
909                 if (dbcon & 3)
910                         set_dbcon(dbcon & ~3);
911                 else
912                         return 1;
913         }
914         return 0;
915 }
916
917 // Return indication of whether or not we stopped because of a
918 // watchpoint or hardware breakpoint. If stopped by a watchpoint,
919 // also set '*data_addr_p' to the data address which triggered the
920 // watchpoint.
921 int cyg_hal_plf_is_stopped_by_hardware(void **data_addr_p)
922 {
923         unsigned fsr, dcsr, dbcon, kind = 0;
924
925         // Check for debug event
926         asm volatile ("mrc p15,0,%0,c5,c0,0" : "=r"(fsr) :);
927         if ((fsr & 0x200) == 0)
928                 return HAL_STUB_HW_STOP_NONE;
929
930         // There was a debug event. Check the MOE for details
931         dcsr = get_dcsr();
932         switch ((dcsr >> 2) & 7) {
933         case 1:  // HW breakpoint
934                 return HAL_STUB_HW_STOP_BREAK;
935         case 2:  // Watchpoint
936                 dbcon = get_dbcon();
937                 if (dbcon & 0x100) {
938                         // dbr1 is used as address mask
939                         kind = dbcon & 3;
940                         *data_addr_p = (void *)get_dbr0();
941                 }
942                 if (kind == 1)
943                         return HAL_STUB_HW_STOP_WATCH;
944                 if (kind == 2)
945                         return HAL_STUB_HW_STOP_AWATCH;
946                 if (kind == 3)
947                         return HAL_STUB_HW_STOP_RWATCH;
948                 // should never get here
949                 break;
950         }
951         return HAL_STUB_HW_STOP_NONE;
952 }
953 #endif // CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
954
955 #define SCL_LOW         (unsigned char)0x00
956 #define SCL_HIGH        (unsigned char)0x01
957 #define SDA_LOW         (unsigned char)0x00
958 #define SDA_HIGH        (unsigned char)0x02
959 #define I2C_WRITE       (unsigned char)0x00
960 #define I2C_READ        (unsigned char)0x01
961
962 #define WRITE_REG32(__regadr, __val) ((__regadr) = (__val))
963 #define READ_REG32(__regadr) (__regadr)
964
965 #define PXA250_AFREG_BASE       0x40e00054
966 #define PXA250_PINDIR_BASE      0x40e0000c
967 #define PXA250_PINSET_BASE      0x40e00018
968 #define PXA250_PINCLEAR_BASE    0x40e00024
969 #define PXA250_REDGE_BASE       0x40e00030
970 #define PXA250_FEDGE_BASE       0x40e0003c
971 #define PXA250_DEDGE_BASE       0x40e00048
972 #define PXA250_PINLEVEL_BASE    0x40e00000
973
974 void pin_i2c_setup(pin_i2c_t *pin_data)
975 {
976         // configure pins as GPIO function
977         set_alternate_function((unsigned char)pin_data->scl_no, 0);
978         set_alternate_function((unsigned char)pin_data->sda_no, 0);
979
980         // set both pins to input
981         set_pin_dir((unsigned char)pin_data->scl_no, 0);                /* 0=input 1=output */
982         set_pin_dir((unsigned char)pin_data->sda_no, 0);                /* 0=input 1=output */
983
984         // clear all output registers
985         clear_pin((unsigned char)pin_data->scl_no);
986         clear_pin((unsigned char)pin_data->sda_no);
987 }
988
989 void bus_out(pin_i2c_t *pin_data, unsigned char pdata)
990 {
991         switch (pdata & 0x03) {
992         case 0:
993                 set_pin_dir((unsigned char)pin_data->scl_no, 1);        /* 0=input 1=output */
994                 set_pin_dir((unsigned char)pin_data->sda_no, 1);        /* 0=input 1=output */
995                 break;
996         case 1:
997                 set_pin_dir((unsigned char)pin_data->scl_no, 0);        /* 0=input 1=output */
998                 set_pin_dir((unsigned char)pin_data->sda_no, 1);        /* 0=input 1=output */
999                 break;
1000         case 2:
1001                 set_pin_dir((unsigned char)pin_data->scl_no, 1);        /* 0=input 1=output */
1002                 set_pin_dir((unsigned char)pin_data->sda_no, 0);        /* 0=input 1=output */
1003                 break;
1004         case 3:
1005                 set_pin_dir((unsigned char)pin_data->scl_no, 0);        /* 0=input 1=output */
1006                 set_pin_dir((unsigned char)pin_data->sda_no, 0);        /* 0=input 1=output */
1007                 break;
1008         }
1009         return;
1010 }
1011
1012 int bus_in(pin_i2c_t *pin_data)
1013 {
1014         int result;
1015
1016         result = get_pin_status((unsigned char)pin_data->sda_no);
1017         if (result < 0) {
1018                 //dprintf("get_pin_status returned error \n");
1019                 return 1;
1020         } else {
1021                 return result;
1022         }
1023 }
1024
1025 void i2c_start(pin_i2c_t *pin_data)
1026 {
1027         //dprintf("pin status is %d\n", get_pin_status((unsigned char)pin_data->sda_no));
1028
1029         bus_out(pin_data, SCL_HIGH | SDA_LOW);
1030         HAL_DELAY_US(10);
1031
1032         bus_out(pin_data, SCL_HIGH | SDA_HIGH);
1033         HAL_DELAY_US(10);
1034
1035         bus_out(pin_data, SCL_HIGH | SDA_LOW);
1036         HAL_DELAY_US(10);
1037
1038         bus_out(pin_data, SCL_LOW | SDA_LOW);
1039         HAL_DELAY_US(10);
1040 }
1041
1042 void i2c_stop(pin_i2c_t *pin_data)
1043 {
1044         bus_out(pin_data, SCL_LOW | SDA_LOW);
1045         HAL_DELAY_US(10);
1046         bus_out(pin_data, SCL_HIGH | SDA_LOW);
1047         HAL_DELAY_US(10);
1048         bus_out(pin_data, SCL_HIGH | SDA_HIGH);
1049         HAL_DELAY_US(10);
1050 }
1051
1052 int i2c_read_ack(pin_i2c_t *pin_data)
1053 {
1054         bus_out(pin_data, SCL_LOW | SDA_HIGH);
1055         HAL_DELAY_US(10);
1056         bus_out(pin_data, SCL_HIGH | SDA_HIGH);
1057         HAL_DELAY_US(10);
1058         if (bus_in(pin_data)) {
1059                 bus_out(pin_data, SCL_LOW | SDA_HIGH);
1060                 HAL_DELAY_US(10);
1061                 return -2;
1062         } else {
1063                 bus_out(pin_data, SCL_LOW | SDA_HIGH);
1064                 HAL_DELAY_US(10);
1065                 return 0;
1066         }
1067 }
1068
1069 void i2c_write_ack(pin_i2c_t *pin_data)
1070 {
1071         bus_out(pin_data, SCL_LOW | SDA_LOW);
1072         HAL_DELAY_US(10);
1073         bus_out(pin_data, SCL_HIGH | SDA_LOW);
1074         HAL_DELAY_US(10);
1075         bus_out(pin_data, SCL_LOW | SDA_LOW);
1076         HAL_DELAY_US(10);
1077 }
1078
1079 void i2c_write_nack(pin_i2c_t *pin_data)
1080 {
1081         bus_out(pin_data, SCL_LOW | SDA_HIGH);
1082         HAL_DELAY_US(10);
1083         bus_out(pin_data, SCL_HIGH | SDA_HIGH);
1084         HAL_DELAY_US(10);
1085         bus_out(pin_data, SCL_LOW | SDA_HIGH);
1086         HAL_DELAY_US(10);
1087 }
1088
1089 void i2c_slave_addr(pin_i2c_t *pin_data, unsigned char dev, unsigned char mode)
1090 {
1091         i2c_write(pin_data, dev | mode);
1092 }
1093
1094 void i2c_read(pin_i2c_t *pin_data, unsigned char *res)
1095 {
1096         unsigned char in = 0;
1097         unsigned char bit = 0x80;
1098
1099         while (bit) {
1100                 bus_out(pin_data, SCL_LOW | SDA_HIGH);
1101                 HAL_DELAY_US(10);
1102                 bus_out(pin_data, SCL_HIGH | SDA_HIGH);
1103                 HAL_DELAY_US(10);
1104                 if (bus_in(pin_data))
1105                         in |= bit;
1106                 bus_out(pin_data, SCL_LOW | SDA_HIGH);
1107                 HAL_DELAY_US(10);
1108                 bit >>= 1;
1109         }
1110         *res = in;
1111 }
1112
1113 void i2c_write(pin_i2c_t *pin_data, unsigned char val)
1114 {
1115         unsigned char out;
1116         unsigned char bit = 0x80;
1117
1118         while (bit) {
1119                 out = (bit & val) ? SDA_HIGH : SDA_LOW;
1120                 bus_out(pin_data, SCL_LOW | out);
1121                 HAL_DELAY_US(10);
1122                 bus_out(pin_data, SCL_HIGH | out);
1123                 HAL_DELAY_US(10);
1124                 bus_out(pin_data, SCL_LOW | out);
1125                 HAL_DELAY_US(10);
1126                 bit >>= 1;
1127         }
1128 }
1129
1130 /* ================================================================ */
1131 /*
1132     function:   se_read
1133
1134     paramters:  unsigned char addr      start address in ser. EEPROM
1135                 unsigned int  numb      number of bytes to be read
1136                 char *dat               pointer to data buffer
1137
1138     ret. val.:  int                     = 0, every thing ok
1139                                           else, device not av., or not ready
1140
1141 */
1142 int se_read(pin_i2c_t *pin_data, unsigned char addr, unsigned char dev_address,
1143             unsigned int numb, char *dat)
1144 {
1145         unsigned int i;
1146
1147         i2c_start(pin_data);
1148         i2c_slave_addr(pin_data, dev_address, I2C_WRITE);
1149         if (i2c_read_ack(pin_data) < 0) {
1150                 i2c_stop(pin_data);
1151                 return -1;
1152         }
1153         i2c_write(pin_data, addr);        /* read from start address */
1154         if (i2c_read_ack(pin_data) < 0) {
1155                 i2c_stop(pin_data);
1156                 return -1;
1157         }
1158
1159         i2c_start(pin_data);
1160         i2c_slave_addr(pin_data, dev_address, I2C_READ);
1161         if (i2c_read_ack(pin_data) < 0) {
1162                 i2c_stop(pin_data);
1163                 return -1;
1164         }
1165
1166         for (i = 0; i < numb - 1; i++) {
1167                 i2c_read(pin_data, dat++);
1168                 i2c_write_ack(pin_data);
1169         }
1170         i2c_read(pin_data, dat);
1171         i2c_stop(pin_data);
1172
1173         return 0;
1174 }
1175
1176 /* ================================================================ */
1177 /*
1178     function:   se_write
1179
1180     paramters:  unsigned char addr      start address in ser. EEPROM
1181                 unsigned char val       value to write
1182
1183     ret. val.:  int                     = 0, every thing ok
1184                                           else, device not av., or not ready
1185
1186 */
1187 int se_write(pin_i2c_t *pin_data, unsigned char addr,unsigned char dev_address, unsigned char val)
1188 {
1189         i2c_start(pin_data);
1190         i2c_slave_addr(pin_data, dev_address, I2C_WRITE);
1191         if (i2c_read_ack(pin_data) < 0) {
1192                 i2c_stop(pin_data);
1193                 return -1;
1194         }
1195         i2c_write(pin_data, addr);
1196         if (i2c_read_ack(pin_data) < 0) {
1197                 i2c_stop(pin_data);
1198                 return -1;
1199         }
1200         i2c_write(pin_data, val);
1201         if (i2c_read_ack(pin_data) < 0) {
1202                 i2c_stop(pin_data);
1203                 return -1;
1204         }
1205         i2c_stop(pin_data);
1206         HAL_DELAY_US(10000);
1207         return 0;
1208 }
1209
1210 /* ================================================================ */
1211 /*
1212     function:   ltc1663_pwrite
1213
1214     paramters:  unsigned dev_address            device address of chip
1215                         unsigned char command           command byte
1216                 unsigned short val              value to write
1217
1218     ret. val.:  int                             = 0, every thing ok
1219                                                         else, device not av., or not ready
1220
1221 */
1222 int ltc1663_write(pin_i2c_t *pin_data, unsigned char dev_address, unsigned char command,
1223                   unsigned short val)
1224 {
1225         i2c_start(pin_data);
1226         i2c_slave_addr(pin_data, dev_address, I2C_WRITE);
1227         if (i2c_read_ack(pin_data) < 0) {
1228                 i2c_stop(pin_data);
1229                 return -1;
1230         }
1231         i2c_write(pin_data, command);
1232         if (i2c_read_ack(pin_data) < 0) {
1233                 i2c_stop(pin_data);
1234                 return -1;
1235         }
1236         i2c_write(pin_data, (unsigned char)val&0xff);
1237         if (i2c_read_ack(pin_data) < 0) {
1238                 i2c_stop(pin_data);
1239                 return -1;
1240         }
1241         i2c_write(pin_data, (unsigned char)((val&0xff00)>>8));
1242         if (i2c_read_ack(pin_data) < 0) {
1243                 i2c_stop(pin_data);
1244                 return -1;
1245         }
1246         i2c_stop(pin_data);
1247         HAL_DELAY_US(100);
1248         return 0;
1249 }
1250
1251 // -----------------------------------------------------------------------
1252 int set_alternate_function(unsigned char gpio_number, unsigned char function_code)
1253 {
1254         unsigned int register_offset;
1255         unsigned int bit_offset;
1256         unsigned long mask;
1257         unsigned long reg_adr;
1258         unsigned long org_value;
1259         unsigned long new_value;
1260
1261         // do some checking
1262         if (gpio_number >= NUM_GPIOS) {
1263                 //dprintf("GPIO pin number %d is out of range!\n", gpio_number);
1264                 return 0;
1265         }
1266
1267         if (function_code > 3) {
1268                 //dprintf("GPIO alternate function code %d is out of range\n", function_code);
1269                 return 0;
1270         }
1271
1272         register_offset = gpio_number / 16;
1273
1274         bit_offset = gpio_number % 16;
1275         mask = 3 << (bit_offset*2);
1276
1277         reg_adr = PXA250_AFREG_BASE + register_offset * 4;
1278
1279         org_value = READ_REG32(reg_adr);
1280
1281         new_value = (org_value & (~mask)) | (function_code << (bit_offset*2));
1282
1283         WRITE_REG32(reg_adr, new_value);
1284         return 1;
1285 }
1286
1287 int set_pin_dir(unsigned char gpio_number, unsigned char dir_code)
1288 {
1289         unsigned int register_offset;
1290         unsigned int bit_offset;
1291         unsigned long mask;
1292         unsigned long reg_adr;
1293         unsigned long org_value;
1294         unsigned long new_value;
1295
1296         // do some checking
1297         if (gpio_number >= NUM_GPIOS) {
1298                 //dprintf("GPIO pin number %d is out of range!\n", gpio_number);
1299                 return 0;
1300         }
1301
1302         if (dir_code > 1) {
1303                 //dprintf("GPIO alternate function code %d is out of range\n", dir_code);
1304                 return 0;
1305         }
1306
1307         register_offset = gpio_number / 32;
1308
1309         bit_offset = gpio_number % 32;
1310         mask = 1 << (bit_offset);
1311
1312         reg_adr = PXA250_PINDIR_BASE + register_offset * 4;
1313
1314         org_value = READ_REG32(reg_adr);
1315
1316         new_value = (org_value & (~mask)) | (dir_code << (bit_offset));
1317
1318         WRITE_REG32(reg_adr, new_value);
1319         return 1;
1320 }
1321
1322 int set_rising_edge(unsigned char gpio_number, unsigned char edge_code)
1323 {
1324         unsigned int register_offset;
1325         unsigned int bit_offset;
1326         unsigned long mask;
1327         unsigned long reg_adr;
1328         unsigned long org_value;
1329         unsigned long new_value;
1330
1331         // do some checking
1332         if (gpio_number >= NUM_GPIOS) {
1333                 //dprintf("GPIO pin number %d is out of range!\n", gpio_number);
1334                 return 0;
1335         }
1336         if (edge_code > 1) {
1337                 //dprintf("rising edge value sould be 0 or 1, not %d\n", edge_code);
1338                 return 0;
1339         }
1340         register_offset = gpio_number / 32;
1341
1342         bit_offset = gpio_number % 32;
1343         mask = 1 << (bit_offset);
1344
1345         reg_adr = PXA250_REDGE_BASE + register_offset * 4;
1346
1347         org_value = READ_REG32(reg_adr);
1348
1349         new_value = (org_value & (~mask)) | (edge_code << (bit_offset));
1350         WRITE_REG32(reg_adr, new_value);
1351         return 1;
1352 }
1353
1354 int set_falling_edge(unsigned char gpio_number, unsigned char edge_code)
1355 {
1356         unsigned int register_offset;
1357         unsigned int bit_offset;
1358         unsigned long mask;
1359         unsigned long reg_adr;
1360         unsigned long org_value;
1361         unsigned long new_value;
1362
1363         // do some checking
1364         if (gpio_number >= NUM_GPIOS) {
1365                 //dprintf("GPIO pin number %d is out of range!\n", gpio_number);
1366                 return 0;
1367         }
1368
1369         if (edge_code > 1) {
1370                 //dprintf("falling edge value sould be 0 or 1, not %d\n", edge_code);
1371                 return 0;
1372         }
1373
1374         register_offset = gpio_number / 32;
1375
1376         bit_offset = gpio_number % 32;
1377         mask = 1 << (bit_offset);
1378
1379         reg_adr = PXA250_FEDGE_BASE + register_offset * 4;
1380
1381         org_value = READ_REG32(reg_adr);
1382
1383         new_value = (org_value & (~mask)) | (edge_code << (bit_offset));
1384         WRITE_REG32(reg_adr, new_value);
1385         return 1;
1386 }
1387
1388 int set_pin(unsigned char gpio_number)
1389 {
1390         unsigned int register_offset;
1391         unsigned int bit_offset;
1392         unsigned long mask;
1393         unsigned long reg_adr;
1394         unsigned long org_value;
1395         unsigned long new_value;
1396
1397         // do some checking
1398         if (gpio_number >= NUM_GPIOS) {
1399                 //dprintf("GPIO pin number %d is out of range!\n", gpio_number);
1400                 return 0;
1401         }
1402
1403         register_offset = gpio_number / 32;
1404
1405         bit_offset = gpio_number % 32;
1406         mask = 1 << (bit_offset);
1407
1408         reg_adr = PXA250_PINSET_BASE + register_offset * 4;
1409
1410         org_value = 0;
1411
1412         new_value = (org_value & (~mask)) | (1 << (bit_offset));
1413
1414         WRITE_REG32(reg_adr, new_value);
1415         return 1;
1416
1417 }
1418
1419 int clear_pin(unsigned char gpio_number)
1420 {
1421         unsigned int register_offset;
1422         unsigned int bit_offset;
1423         unsigned long mask;
1424         unsigned long reg_adr;
1425         unsigned long org_value;
1426         unsigned long new_value;
1427
1428         // do some checking
1429         if (gpio_number >= NUM_GPIOS) {
1430                 //dprintf("GPIO pin number %d is out of range!\n", gpio_number);
1431                 return 0;
1432         }
1433
1434         register_offset = gpio_number / 32;
1435
1436         bit_offset = gpio_number % 32;
1437         mask = 1 << (bit_offset);
1438
1439         reg_adr = PXA250_PINCLEAR_BASE + register_offset * 4;
1440
1441         org_value = 0;
1442
1443         new_value = (org_value & (~mask)) | (1 << (bit_offset));
1444
1445         WRITE_REG32(reg_adr, new_value);
1446         return 1;
1447
1448 }
1449
1450 int get_pin_status(unsigned char gpio_number)
1451 {
1452         unsigned int register_offset;
1453         unsigned int bit_offset;
1454         unsigned long mask;
1455         unsigned long reg_adr;
1456         unsigned long return_value;
1457
1458         // do some checking
1459         if (gpio_number >= NUM_GPIOS) {
1460                 //dprintf("GPIO pin number %d is out of range!\n", gpio_number);
1461                 return -1;
1462         }
1463
1464         register_offset = gpio_number / 32;
1465
1466         bit_offset = gpio_number % 32;
1467         mask = 1 << (bit_offset);
1468
1469         reg_adr = PXA250_PINLEVEL_BASE + register_offset * 4;
1470
1471         return_value = (READ_REG32(reg_adr) & mask) >> bit_offset;
1472
1473         return return_value;
1474 }
1475
1476 int clear_edge(unsigned char gpio_number)
1477 {
1478         unsigned int register_offset;
1479         unsigned int bit_offset;
1480         unsigned long mask;
1481         unsigned long reg_adr;
1482         unsigned long org_value;
1483         unsigned long new_value;
1484
1485         // do some checking
1486         if (gpio_number >= NUM_GPIOS) {
1487                 //dprintf("GPIO pin number %d is out of range!\n", gpio_number);
1488                 return 0;
1489         }
1490
1491         register_offset = gpio_number / 32;
1492
1493         bit_offset = gpio_number % 32;
1494         mask = 1 << (bit_offset);
1495
1496         reg_adr = PXA250_DEDGE_BASE + register_offset * 4;
1497
1498         org_value = READ_REG32(reg_adr);
1499
1500         new_value = (org_value & (~mask)) | (1 << (bit_offset));
1501         WRITE_REG32(reg_adr, new_value);
1502
1503         return 1;
1504 }
1505
1506 int detect_edge(unsigned char gpio_number)
1507 {
1508         unsigned int register_offset;
1509         unsigned int bit_offset;
1510         unsigned long mask;
1511         unsigned long reg_adr;
1512         unsigned long org_value;
1513
1514         // do some checking
1515         if (gpio_number >= NUM_GPIOS) {
1516                 //dprintf("GPIO pin number %d is out of range!\n", gpio_number);
1517                 return 0;
1518         }
1519
1520         register_offset = gpio_number / 32;
1521
1522         bit_offset = gpio_number % 32;
1523         mask = 1 << (bit_offset);
1524
1525         reg_adr = PXA250_DEDGE_BASE + register_offset * 4;
1526
1527         org_value = READ_REG32(reg_adr);
1528
1529         return !!(org_value & mask);
1530 }
1531
1532 void init_i2c(void)
1533 {
1534         HAL_WRITE_UINT32(ICR, ICR_UR);                          // reset i2c_unit;
1535         HAL_WRITE_UINT32(ICR, ICR_IUE | ICR_SCLE | ICR_GCD);
1536 }
1537
1538 //FIXME: insert timeout into while loop
1539 cyg_int32 write_i2c_pcf8574(cyg_uint8 device_adr,  cyg_uint8 dat_value)
1540 {
1541         cyg_uint32      value;
1542         unsigned int    retries;
1543
1544 // write device address now
1545         HAL_WRITE_UINT32(IDBR, (device_adr & 0xfe));
1546         HAL_READ_UINT32(ICR, value);
1547         value = value & ~(ICR_STOP | ICR_ALDIE);
1548         HAL_WRITE_UINT32(ICR, value | ICR_START | ICR_TB);
1549
1550         HAL_READ_UINT32(ISR, value);
1551         value &= ISR_ITE;
1552         while (!value) {        // wait for Transmit Empty
1553                 HAL_READ_UINT32(ISR, value);
1554                 value &= ISR_ITE;
1555         }
1556         HAL_READ_UINT32(ISR, value);
1557         if (value & ISR_BED) {
1558
1559                 //diag_printf("I2C: bus error, status after write device address is: %06X\n", value);
1560                 HAL_READ_UINT32(ICR, value);
1561                 HAL_WRITE_UINT32(ICR, value | ICR_MA);          // send master abort
1562                 HAL_DELAY_US(10000);
1563                 HAL_WRITE_UINT32(ICR, value & ~ICR_MA);
1564                 return -1;
1565         }
1566         HAL_WRITE_UINT32(ISR, ISR_ITE); // clear ITE status
1567
1568 // write data now
1569         HAL_WRITE_UINT32(IDBR, (dat_value & 0xff));
1570         HAL_READ_UINT32(ICR, value);
1571         value &=  ~ICR_START;
1572         HAL_WRITE_UINT32(ICR, value | ICR_TB | ICR_STOP);
1573
1574         HAL_READ_UINT32(ISR, value);
1575         retries = 1000000;
1576         while (!(value & ISR_ITE)) {    // wait for Transmit Empty
1577                 HAL_READ_UINT32(ISR, value);
1578         }
1579         if (!(value & ISR_ITE)) {
1580                 diag_printf("I2C: timeout waiting for ITE\n");
1581                 return -1;
1582         }
1583         if (value & ISR_BED) {
1584                 //diag_printf("I2C: bus error, status after write device address is: %06X\n", value);
1585                 HAL_READ_UINT32(ICR, value);
1586                 HAL_WRITE_UINT32(ICR, value | ICR_MA);          // send master abort
1587                 HAL_DELAY_US(10000);
1588                 HAL_WRITE_UINT32(ICR, value & ~ICR_MA);
1589                 return -1;
1590         }
1591         HAL_WRITE_UINT32(ISR, ISR_ITE); // clear ITE status
1592
1593         HAL_READ_UINT32(ICR, value);
1594         value = value  &  ~(ICR_STOP | ICR_START | ICR_TB);
1595         HAL_WRITE_UINT32(ICR, value);
1596
1597         return 0;
1598 }
1599
1600 //FIXME: insert timeout into while loop
1601 cyg_int32 read_i2c_pcf8574(cyg_uint8 device_adr)
1602 {
1603         cyg_uint32      value;
1604         unsigned int    retries;
1605
1606         // write device address now
1607         HAL_WRITE_UINT32(IDBR, (device_adr | 0x01));
1608
1609         HAL_READ_UINT32(ICR, value);
1610         value &= ~ICR_STOP;
1611         HAL_WRITE_UINT32(ICR, value | ICR_START | ICR_TB);
1612
1613         HAL_READ_UINT32(ISR, value);
1614         retries = 1000000;
1615         while (!(value & ISR_ITE)) {    // wait for Transmit Empty
1616                 HAL_READ_UINT32(ISR, value);
1617         }
1618         if (!(value & ISR_ITE)) {
1619                 diag_printf("I2C: timeout waiting for ITE\n");
1620                 return -1;
1621         }
1622         if (value & ISR_BED) {
1623                 //diag_printf("I2C: bus error, status after write device address is: %06X\n", value);
1624                 HAL_READ_UINT32(ICR, value);
1625                 HAL_WRITE_UINT32(ICR, value | ICR_MA);          // send master abort
1626                 HAL_DELAY_US(10000);
1627                 HAL_WRITE_UINT32(ICR, value & ~ICR_MA);
1628                 return -1;
1629         }
1630         HAL_WRITE_UINT32(ISR, ISR_ITE); // clear ITE status
1631
1632         // read data now
1633         HAL_READ_UINT32(ICR, value);
1634         value &= ~ICR_START;
1635         HAL_WRITE_UINT32(ICR,  value |ICR_TB | ICR_STOP | ICR_ACKNAK);
1636
1637         HAL_READ_UINT32(ISR, value);
1638         value &= ISR_IRF;
1639         while (!value) {        // wait for Receive Buffer full
1640                 HAL_READ_UINT32(ISR, value);
1641                 value &= ISR_IRF;
1642         }
1643
1644         HAL_WRITE_UINT32(ISR, ISR_IRF); // clear ITE status
1645
1646         HAL_READ_UINT32(ICR, value);
1647         value = value & ~(ICR_STOP | ICR_START | ICR_TB | ICR_ACKNAK);
1648         HAL_WRITE_UINT32(ICR, value);
1649
1650         HAL_READ_UINT32(IDBR, value);
1651
1652         return value & 0xff;
1653 }
1654 /*------------------------------------------------------------------------*/
1655 // EOF triton270_misc.c