]> git.kernelconcepts.de Git - karo-tx-redboot.git/blob - packages/hal/arm/xscale/triton/v2_0/src/triton_misc.c
RedBoot TX53 Release 2012-02-15
[karo-tx-redboot.git] / packages / hal / arm / xscale / triton / v2_0 / src / triton_misc.c
1 //==========================================================================
2 //
3 //      triton_misc.c
4 //
5 //      HAL misc board support code for XScale TRITON
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:         14th January 2003 (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_triton.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 #ifdef CYGPKG_HAL_ARM_XSCALE_TRITON_ETN_HAE
96 // settings for display
97 //
98 //
99 //
100
101 #define LCCR0_ENB       (0)     // enable LCD controlle, we do this later
102 #define LCCR0_CMS       (0)     // color operation enabled
103 #define LCCR0_SDS       (0)     // Single Panel Display
104 #define LCCR0_LDM       (1)     // LCD disable done does not generate interrupts
105 #define LCCR0_SFM       (1)     // Start of Frame does not generate interrupts
106 #define LCCR0_IUM       (1)     // FIFO underrun errors do not generate interrupts
107 #define LCCR0_EFM       (1)     // end of frame condition does not generate interrupts
108 #define LCCR0_PAS       (1)     // active TFT
109 #define LCCR0_DPD       (0)     // no double pixel data
110 #define LCCR0_DIS       (0)     // not disabled
111 #define LCCR0_QDM       (1)     // quick disable does not generate an interrupt
112 #define LCCR0_PDD       (0)     // no palette DMA request delay
113 #define LCCR0_BM        (1)     // Branch Start does not generate an interrupt
114 #define LCCR0_OUM       (1)     // FIFO underrun does not generate interrupts
115
116 #define LCCR1_PPL       (800-1) // pixels per line -1 (must be a multiple of 8 for 4 bit pixels)
117 #define LCCR1_HSW       (30-1)  // Horizontal Sync pulse Width -1
118 #define LCCR1_ELW       (100-1) // End of Line Wait -1
119 #define LCCR1_BLW       (180-1) // Beginning of Line Wait -1
120
121 #define LCCR2_LPP       (600-1) // lines per channel -1
122 #define LCCR2_VSW       (5-1)   // vertical sync pulse with -1 22
123 #define LCCR2_EFW       (13-1)  // End of Frame line clock wait count -1
124 #define LCCR2_BFW       (14-1)  // Beginning of frame line clock wait count -1
125
126 #define LCCR3_PCD       (1)     // Pixel clock divisor
127 // Internal PixClock = 99,5 MHz / 2*(PCD+1)
128 // Note: with DPC=1, double clock is twice of internal
129 //      PCD = 0  ->     Internal Pixel Clock = 49,75 MHz
130 //  PCD = 1  ->  Internal Pixel Clock = 24,88 MHz
131 //  PCD = 2  ->  Internal Pixel Clock = 16,58 MHz
132 //  PCD = 3  ->  Internal Pixel Clock = 12,44 MHz
133 //  PCD = 4  ->  Internal Pixel Clock =  9,95 MHz
134 //  PCD = 5  -> Internal Pixel Clock =  8,29 MHz
135 //  PCD = 6  -> Internal Pixel Clock =  7,11 MHz
136 //  PCD = 7  -> Internal Pixel Clock =  6,22 MHz
137 //  PCD = 8  -> Internal Pixel Clock =  5,53 MHz
138 //  PCD = 9  -> Internal Pixel Clock =  4,98 MHz
139 //  PCD = 10 -> Internal Pixel Clock =  4,52 MHz
140 //  PCD = 20 -> Internal Pixel Clock =  2,37 MHz
141 //      PCD     = 30 -> Internal Pixel Clock =  1,61 MHz
142
143 #define LCCR3_ACB       (0)     // AC bias pin frequency, not used in active mode
144 #define LCCR3_API       (0)     // AC bias Pin transitions per interrupt, not used in active mode
145 #define LCCR3_VSP       (1)     // vertical sync polarity - > active low
146 #define LCCR3_HSP       (1)     // horizontal sync polarity -> active low
147 #define LCCR3_PCP       (0)     // pixel clock polarity -> pixels sampled with falling edge
148 #define LCCR3_OEP       (0)     // Blank polarity -> active high
149 #define LCCR3_BPP       (0)     // bits per pixel -> 1 bits
150 #define LCCR3_DPC       (0)     // Double pixel clock disabled
151 #endif
152
153 void coldstart(void)
154 {
155 #ifdef CYGPKG_HAL_ARM_XSCALE_TRITON_ETN_HAE
156         static unsigned long __attribute__ ((aligned (16))) descriptor[4] = {
157                 descriptor, 0, 0, 800 * 600 / 8,
158         };
159         static unsigned long value;
160
161         set_pin_dir(11, 0);
162         set_alternate_function(11, 0);
163
164         set_pin_dir(23, 0);
165         set_alternate_function(23, 0);
166
167         set_pin_dir(24, 0);
168         set_alternate_function(24, 0);
169
170         set_pin_dir(25, 0);
171         set_alternate_function(25, 0);
172
173         set_pin_dir(26, 0);
174         set_alternate_function(26, 0);
175
176         set_pin_dir(33, 0);
177         set_alternate_function(33, 0);
178
179         set_pin_dir(58, 1);             // LDD00
180         set_pin_dir(59, 1);             // LDD01
181         set_pin_dir(60, 1);             // LDD02
182         set_pin_dir(61, 1);             // LDD03
183         set_pin_dir(62, 1);             // LDD04
184         set_pin_dir(63, 1);             // LDD05
185         set_pin_dir(64, 1);             // LDD06
186         set_pin_dir(65, 1);             // LDD07
187         set_pin_dir(66, 1);             // LDD08
188         set_pin_dir(67, 1);             // LDD09
189         set_pin_dir(68, 1);             // LDD10
190         set_pin_dir(69, 1);             // LDD11
191         set_pin_dir(70, 1);             // LDD12
192         set_pin_dir(71, 1);             // LDD13
193         set_pin_dir(72, 1);             // LDD14
194         set_pin_dir(73, 1);             // LDD15
195         set_pin_dir(74, 1);             // FCLK
196         set_pin_dir(75, 1);             // LCLK
197         set_pin_dir(76, 1);             // PCLK
198         set_pin_dir(77, 1);             // DE
199
200         clear_pin(58);          // LDD00
201         clear_pin(59);          // LDD01
202         clear_pin(60);          // LDD02
203         clear_pin(61);          // LDD03
204         clear_pin(62);          // LDD04
205         clear_pin(63);          // LDD05
206         clear_pin(64);          // LDD06
207         clear_pin(65);          // LDD07
208         clear_pin(66);          // LDD08
209         clear_pin(67);          // LDD09
210         clear_pin(68);          // LDD10
211         clear_pin(69);          // LDD11
212         clear_pin(70);          // LDD12
213         clear_pin(71);          // LDD13
214         clear_pin(72);          // LDD14
215         clear_pin(73);          // LDD15
216         set_pin(74);            // FCLK
217         set_pin(75);            // LCLK
218         clear_pin(76);          // PCLK
219         clear_pin(77);          // DE
220
221         set_alternate_function(74,2);   // FCLK
222         set_alternate_function(75,2);   // LCLK
223         set_alternate_function(76,2);   // PCLK
224         set_alternate_function(77,2);   // BIAS
225
226         set_pin_dir(78, 0);
227         set_alternate_function(78, 0);
228
229         set_pin_dir(79, 0);
230         set_alternate_function(79, 0);
231
232         set_pin_dir(80, 0);
233         set_alternate_function(80, 0);
234
235         HAL_WRITE_UINT32(LCCR0, (LCCR0_ENB |
236                                  (LCCR0_CMS << 1) |
237                                  (LCCR0_SDS << 2) |
238                                  (LCCR0_LDM <<3) |
239                                  (LCCR0_SFM << 4) |
240                                  (LCCR0_IUM << 5)  |
241                                  (LCCR0_EFM << 6)  |
242                                  (LCCR0_PAS <<7)  |
243                                  (LCCR0_DPD << 9) |
244                                  (LCCR0_DIS <<10)  |
245                                  (LCCR0_QDM <<11) |
246                                  (LCCR0_PDD <<12) |
247                                  (LCCR0_BM << 20) |
248                                  (LCCR0_OUM <<21)));
249
250         HAL_WRITE_UINT32(LCCR1,         (LCCR1_PPL |
251                                          (LCCR1_HSW << 10) |
252                                          (LCCR1_ELW << 16) |
253                                          (LCCR1_BLW << 24)));
254         HAL_WRITE_UINT32(LCCR2,         (LCCR2_LPP |
255                                          (LCCR2_VSW << 10) |
256                                          (LCCR2_EFW << 16) |
257                                          (LCCR2_BFW << 24)));
258         HAL_WRITE_UINT32(LCCR3,         (LCCR3_PCD |
259                                          (LCCR3_ACB << 8) |
260                                          (LCCR3_API << 16) |
261                                          (LCCR3_VSP << 20) |
262                                          (LCCR3_HSP << 21) |
263                                          (LCCR3_PCP << 22) |
264                                          (LCCR3_OEP << 23) |
265                                          (LCCR3_BPP << 24) |
266                                          (LCCR3_DPC << 27)));
267
268         HAL_WRITE_UINT32(FDADR0, (unsigned long)descriptor);
269 #endif
270         HAL_WRITE_UINT32(OSCR, 0);      // initialize os timer counter
271         HAL_WRITE_UINT32(RCNR, 0);      // initialize rtc counter
272         HAL_WRITE_UINT32(RTTR, 0x7FFF); // divide RTC to get 1hz output
273         //
274         // initialize interrupt registers
275         //
276         HAL_WRITE_UINT32(ICMR, 0);      // Pending Interrupts are masked from becoming active
277         HAL_WRITE_UINT32(ICLR, 0);      // Route all Interrupts to CPU IRQ (none to FIQ)
278         HAL_WRITE_UINT32(ICCR, 1);      // Only enabled and unmasked interrupt bring core out of idle
279
280         //
281         //  setup general purpose I/Os (specific to TRITON board)
282         //  must set GPSR/GPCR, then set GPDR, then set GPAFR
283         //
284         //  this is already done in the assembly code.
285
286         //      setup the edge detect registers
287
288         HAL_WRITE_UINT32(GRERx, 0x11);          // rising edge detect registers
289         HAL_WRITE_UINT32(GRERy, 0);
290         HAL_WRITE_UINT32(GRERz, 0);
291         HAL_WRITE_UINT32(GFERx, 0);          // falling edge detect registers
292         HAL_WRITE_UINT32(GFERy, 0);
293         HAL_WRITE_UINT32(GFERz, 0);
294
295         //      clear all  edge detect status bits
296
297         HAL_WRITE_UINT32(GEDRx, 0xffffffff);  // clear all bits
298         HAL_WRITE_UINT32(GEDRy, 0xffffffff);
299         HAL_WRITE_UINT32(GEDRz, 0xffffffff);
300
301         //   setup PCMCIA timing parameters (should be optimized (usteinkohl)
302         //
303         //              this is TRITON specific
304         //
305         //              for about 100 MHz MEMCLK:
306         //                      command setup:                          70 nsec
307         //                      command minimum duration:  170 nsec
308         //                      command hold:                           50 nsec
309
310         HAL_WRITE_UINT32(MCIO0, 0x0000c205);
311         HAL_WRITE_UINT32(MCIO1, 0x0000c205);
312
313         HAL_WRITE_UINT32(MCMEM0, 0x0000c205);
314         HAL_WRITE_UINT32(MCMEM1, 0x0000c205);
315
316         HAL_WRITE_UINT32(MCATT0, 0x0000c205);
317         HAL_WRITE_UINT32(MCATT1, 0x0000c205);
318
319         HAL_WRITE_UINT32(MECR, 0x3);   // set CIT and NOS
320 }
321
322 void reset_cp_dac(void)
323 {
324 #define LTC1663_SY              1
325 #define LTC1663_SD              2
326 #define LTC1663_BG              4
327
328 #ifdef TRITON_X_BOARD
329         pin_i2c_t       dac_pins = {4, 5};
330 #else
331         pin_i2c_t       dac_pins = {13, 14};
332 #endif
333         pin_i2c_setup(&dac_pins);
334         ltc1663_write(&dac_pins, 0x40, LTC1663_BG, 384);
335 }
336
337 void init_i2c_pp(void)
338 {
339         init_i2c();
340         write_i2c_pcf8574(0x40, 0xf3);
341         HAL_DELAY_US(10000);
342         write_i2c_pcf8574(0x40, 0xf7);
343 }
344
345 void hal_hardware_init(void)
346 {
347         cyg_uint32 cken;
348         cyg_uint32 val;
349 #ifdef CYGPKG_HAL_ARM_XSCALE_TRITON_ETN_HAE
350         unsigned long value;
351 #endif
352
353         HAL_READ_UINT32(CKEN, cken);
354         // enable FFUART clock and BTUART clock and STUART
355         HAL_WRITE_UINT32(CKEN, cken | 0xe0);
356
357         // Let the "OS" counter run
358         coldstart();
359
360         // Set up eCos/ROM interfaces
361         hal_if_init(); //ecos, not platform, specifc.  Common to all.  Do not change.
362 #ifdef TRITON_V_CPOWER
363         reset_cp_dac();
364 #endif
365 #if 0
366 #if TRITON_STK==2
367         init_i2c_pp();
368 #endif
369 #endif
370         // Enable caches
371         HAL_DCACHE_ENABLE();  //leave this
372         HAL_ICACHE_ENABLE();    //leave this
373
374         //diag_printf("CKEN register: 0x%08X\n", cken);
375
376         // check if we restart from sleep mode
377         HAL_READ_UINT32(RCSR, val);
378         //HAL_WRITE_UINT32(RCSR, 0xf);          // clear all bits
379         if (val & 0x0f) {
380                 const char *sep = " ";
381                 diag_printf("\nReset caused by:");
382                 if (val & 1) {
383                         diag_printf("%shardware reset pin", sep);
384                         sep = " + ";
385                 }
386                 if (val & 0x02) {
387                         diag_printf("%swatchdog reset", sep);
388                         sep = " + ";
389                 }
390                 if (val & 0x08) {
391                         diag_printf("%sGPIO reset\n", sep);
392                         sep = " + ";
393                 }
394                 if (val & 0x04) {
395                         diag_printf("%ssleep reset", sep);
396                         sep = " + ";
397                         HAL_READ_UINT32(PSPR, val);
398                         if (!val) {
399                                 diag_printf("\nwarning, NULL pointer detected in PSPR register\n");
400                         } else {
401                                 diag_printf("\nrestarting operating system ...\n");
402                                 asm volatile (
403                                               "mov pc, %0;"     // jump to pointer
404                                               :
405                                               : "r"(val)
406                                               );
407                         }
408                 }
409                 diag_printf("\n");
410         } else {
411                 diag_printf("\nwarning, unknown reset source !!!!\n");
412                 diag_printf("RCSR register: 0x%08X\n", val);
413         }
414
415 #ifdef CYGPKG_HAL_ARM_XSCALE_TRITON_ETN_HAE
416         HAL_READ_UINT32(LCCR0, value);
417         value |= 1;                             // enable LCD controller
418         HAL_WRITE_UINT32(LCCR0, value);
419 #endif
420 }
421
422 #include CYGHWR_MEMORY_LAYOUT_H
423 typedef void code_fun(void);
424 void triton_program_new_stack(void *func)
425 {
426         register CYG_ADDRESS stack_ptr asm("sp");
427         register CYG_ADDRESS old_stack asm("r4");
428         register code_fun *new_func asm("r0");
429
430         old_stack = stack_ptr;
431
432         stack_ptr = CYGMEM_REGION_ram + CYGMEM_REGION_ram_SIZE - sizeof(CYG_ADDRESS);
433         new_func = (code_fun*)func;
434         new_func();
435
436         stack_ptr = old_stack;
437 }
438
439 #if 0
440     asm volatile (
441                   "ldr          r1,=0x00000800;" // we use GPIO23 for controlling the debug LED
442
443                   "250961:;"
444                   "ldr          r0,=0x40E00024;"        // GPCR0
445                   "str          r1,     [r0];"          // switch the LED on
446                   
447                   "ldr          r2,=0x00a00000;"        // wait some time
448                   "mov          r3,#1 ;"
449                   "998:;"
450                   "sub          r2, r2, r3;"
451                   "cmp          r2,#0;"
452                   "bne          998b;"
453
454                   "ldr          r0,=0x40E00018;"        // GPSR0
455                   "str          r1,     [r0];"          // switch the LED off
456
457                   "ldr          r2,=0x00a00000;"        // wait some time
458                   "mov          r3,#1;"
459                   "998:;"
460                   "sub          r2, r2, r3;"
461                   "cmp          r2,#0;"
462                   "bne          998b;"
463
464                   "b            250961b;"
465                   :
466                   :
467                   : "r0","r1","r2","r3"
468                   );
469 #endif
470
471 // Initialize the clock
472 static cyg_uint32  clock_period;
473
474 void hal_clock_initialize(cyg_uint32 period)
475 {
476         cyg_uint32 oier;
477
478         // Load match value
479         HAL_WRITE_UINT32(OSMR0, period);
480         clock_period = period;
481
482         // Start the counter
483         HAL_WRITE_UINT32(OSCR, 0);
484         // Clear any pending interrupt
485         HAL_WRITE_UINT32(OSSR, OSSR_TIMER0);
486         // Enable timer 0 interrupt
487         HAL_READ_UINT32(OIER, oier);
488         HAL_WRITE_UINT32(OIER, oier | OIER_TIMER0);
489
490         // Unmask timer 0 interrupt
491         HAL_INTERRUPT_UNMASK(CYGNUM_HAL_INTERRUPT_TIMER0);
492 }
493
494 // This routine is called during a clock interrupt.
495 void hal_clock_reset(cyg_uint32 vector, cyg_uint32 period)
496 {
497         cyg_uint32 oscr;
498
499         // Load new match value
500         HAL_READ_UINT32(OSCR, oscr);
501         HAL_WRITE_UINT32(OSMR0, oscr + period);
502         // Clear any pending interrupt
503         HAL_WRITE_UINT32(OSSR, OSSR_TIMER0);
504 }
505
506 // Read the current value of the clock, returning the number of hardware
507 // "ticks" that have occurred (i.e. how far away the current value is from
508 // the start)
509
510 // Note: The "contract" for this function is that the value is the number
511 // of hardware clocks that have happened since the last interrupt (i.e.
512 // when it was reset).  This value is used to measure interrupt latencies.
513 // However, since the hardware counter runs freely, this routine computes
514 // the difference between the current clock period and the number of hardware
515 // ticks left before the next timer interrupt.
516 void hal_clock_read(cyg_uint32 *pvalue)
517 {
518         int orig;
519         cyg_uint32 oscr;
520         cyg_uint32 osmr0;
521
522         HAL_DISABLE_INTERRUPTS(orig);
523         HAL_READ_UINT32(OSCR, oscr);
524         HAL_READ_UINT32(OSMR0, osmr0);
525         *pvalue = clock_period + oscr - osmr0;
526         HAL_RESTORE_INTERRUPTS(orig);
527 }
528
529 // Delay for some number of micro-seconds
530 void hal_delay_us(cyg_uint32 time)
531 {
532 #if 1
533         cyg_uint32 val = 0;
534         cyg_uint32 ctr;
535
536         HAL_READ_UINT32(OSCR, ctr);
537         while (time-- > 0) {
538                 do {
539                         cyg_uint32 oscr;
540
541                         HAL_READ_UINT32(OSCR, oscr);
542                         if (ctr != oscr) {
543                                 val += 271267;          // 271267ps (3.6864Mhz -> 271.267ns)
544                                 ++ctr;
545                         }
546                 } while (val < 1000000);
547                 val -= 1000000;
548         }
549 #else
550         cyg_uint32 timer_value;
551
552         if (time < 100000) {
553                 timer_value = time * 3686;
554                 timer_value = timer_value / 1000;
555         } else {
556                 timer_value = time / 1000;
557                 timer_value = timer_value * 3686;
558         }
559
560         if (timer_value < 20) {
561                 timer_value = 20;
562         }
563         asm volatile (
564                       "ldr r5, =0x40a0001C;"            // OIER
565                       "mov r7, #1;"
566                       "str r7, [r5];"                   // enable match 0
567
568                       "ldr r5, =0x40a00010;"            // OSCR
569                       "ldr r6, [r5];"
570                       "add r6, r6, %0;"
571                       "ldr r5, =0x40a00000;"            // OS Timer Match Register 0
572                       "str r6, [r5];"
573
574                       "ldr r5, =0x40a00014;"            // OSSR
575                       "mov r7, #1;"
576                       "str r7, [r5];"                   // clear status
577
578                       "1902:;"
579
580                       "ldr r7, [r5];"                   // read OSSR
581                       "and r7, r7, #1;"
582                       "cmp r7, #1;"
583                       "bne 1902b;"
584                       :
585                       : "r"(timer_value)
586                       : "r5","r6","r7"
587                       );
588 #endif
589 }
590
591 typedef cyg_uint32 cyg_ISR(cyg_uint32 vector, CYG_ADDRWORD data);
592
593 extern void cyg_interrupt_post_dsr(CYG_ADDRWORD intr_obj);
594
595 static inline cyg_uint32 hal_call_isr(cyg_uint32 vector)
596 {
597         return 0;
598 }
599
600 // Interrupt handling
601
602 // This routine is called to respond to a hardware interrupt (IRQ).  It
603 // should interrogate the hardware and return the IRQ vector number.
604 int hal_IRQ_handler(void)
605 {
606         cyg_uint32 sources, index;
607
608 #ifdef HAL_EXTENDED_IRQ_HANDLER
609         // Use platform specific IRQ handler, if defined
610         // Note: this macro should do a 'return' with the appropriate
611         // interrupt number if such an extended interrupt exists.  The
612         // assumption is that the line after the macro starts 'normal' processing.
613         HAL_EXTENDED_IRQ_HANDLER(index);
614 #endif
615
616         HAL_READ_UINT32(ICIP, sources);
617         if (sources & 0xff0000) {
618                 index = 16;
619         } else if (sources & 0xff00) {
620                 index = 8;
621         } else if (sources & 0xff) {
622                 index = 0;
623         } else {
624                 index = 24;
625         }
626         do {
627                 if ((1 << index) & sources) {
628                         if (index == CYGNUM_HAL_INTERRUPT_GPIO) {
629                                 // Special case of GPIO cascade.  Search for lowest set bit
630                                 HAL_READ_UINT32(GEDRx, sources);
631                                 index = 0;
632                                 do {
633                                         if (sources & (1 << index)) {
634                                                 return index + 32;
635                                         }
636                                         index++;
637                                 } while (index < 32);
638                                 HAL_READ_UINT32(GEDRy, sources);
639                                 index = 0;
640                                 do {
641                                         if (sources & (1 << index)) {
642                                                 return index + 64;
643                                         }
644                                         index++;
645                                 } while (index < 32);
646                                 HAL_READ_UINT32(GEDRz, sources);
647                                 index = 0;
648                                 do {
649                                         if (sources & (1 << index)) {
650                                                 return index + 96;
651                                         }
652                                         index++;
653                                 } while (index < 22); // GPIOs 64..85
654
655                         }
656                         return index;
657                 }
658                 index++;
659         } while (index & 7);
660
661         return CYGNUM_HAL_INTERRUPT_NONE; // This shouldn't happen!
662 }
663
664 void hal_interrupt_mask(int vector)
665 {
666         cyg_uint32 icmr;
667
668 #ifdef HAL_EXTENDED_INTERRUPT_MASK
669         // Use platform specific handling, if defined
670         // Note: this macro should do a 'return' for "extended" values of 'vector'
671         // Normal vectors are handled by code subsequent to the macro call.
672         HAL_EXTENDED_INTERRUPT_MASK(vector);
673 #endif
674         if (vector >= CYGNUM_HAL_INTERRUPT_GPIO2) {
675                 vector = CYGNUM_HAL_INTERRUPT_GPIO;
676         }
677         HAL_READ_UINT32(ICMR, icmr);
678         HAL_WRITE_UINT32(ICMR, icmr & ~(1 << vector));
679 }
680
681 void hal_interrupt_unmask(int vector)
682 {
683         cyg_uint32 icmr;
684
685 #ifdef HAL_EXTENDED_INTERRUPT_UNMASK
686         // Use platform specific handling, if defined
687         // Note: this macro should do a 'return' for "extended" values of 'vector'
688         // Normal vectors are handled by code subsequent to the macro call.
689         HAL_EXTENDED_INTERRUPT_UNMASK(vector);
690 #endif
691
692         if (vector >= CYGNUM_HAL_INTERRUPT_GPIO2) {
693                 vector = CYGNUM_HAL_INTERRUPT_GPIO;
694         }
695         HAL_READ_UINT32(ICMR, icmr);
696         HAL_WRITE_UINT32(ICMR, icmr | (1 << vector));
697 }
698
699 void hal_interrupt_acknowledge(int vector)
700 {
701         cyg_uint32 rtsr;
702
703 #if DEBUG_INT
704         diag_printf("void hal_interrupt_acknowledge(int vector) entered ...\n");
705         diag_printf("vector = %d     \n", vector);
706 #endif
707         switch (vector) {
708         case CYGNUM_HAL_INTERRUPT_ALARM:
709                 HAL_READ_UINT32(RTSR, rtsr);
710                 HAL_WRITE_UINT32(RTSR, (rtsr & ~0x2553) | 0x1);
711                 break;
712         case CYGNUM_HAL_INTERRUPT_HZ:
713                 HAL_READ_UINT32(RTSR, rtsr);
714                 HAL_WRITE_UINT32(RTSR, (rtsr & ~0x2553) | 0x2);
715                 break;
716         case CYGNUM_HAL_INTERRUPT_TIMER3:
717                 HAL_WRITE_UINT32(OSSR, 0x08);
718                 break;
719         case CYGNUM_HAL_INTERRUPT_TIMER2:
720                 HAL_WRITE_UINT32(OSSR, 0x04);
721                 break;
722         case CYGNUM_HAL_INTERRUPT_TIMER1:
723                 HAL_WRITE_UINT32(OSSR, 0x02);
724                 break;
725         case CYGNUM_HAL_INTERRUPT_TIMER0:
726                 HAL_WRITE_UINT32(OSSR, 0x01);
727                 break;
728         case CYGNUM_HAL_INTERRUPT_DMA:
729                 // user specific code here
730                 break;
731         case CYGNUM_HAL_INTERRUPT_SSP:
732                 // user specific code here
733                 break;
734         case CYGNUM_HAL_INTERRUPT_MMC:
735                 // user specific code here
736                 break;
737         case CYGNUM_HAL_INTERRUPT_FFUART:
738                 // user specific code here
739                 break;
740         case CYGNUM_HAL_INTERRUPT_BTUART:
741                 // user specific code here
742                 break;
743         case CYGNUM_HAL_INTERRUPT_STUART:
744                 // user specific code here
745                 break;
746         case CYGNUM_HAL_INTERRUPT_ICP:
747                 // user specific code here
748                 break;
749         case CYGNUM_HAL_INTERRUPT_I2S:
750                 // user specific code here
751                 break;
752         case CYGNUM_HAL_INTERRUPT_LCD:
753                 // user specific code here
754                 break;
755         case CYGNUM_HAL_INTERRUPT_AC97:
756                 // user specific code here
757                 break;
758         case CYGNUM_HAL_INTERRUPT_I2C:
759                 // user specific code here
760                 break;
761         case CYGNUM_HAL_INTERRUPT_PMU:
762                 // user specific code here
763                 break;
764         case CYGNUM_HAL_INTERRUPT_USB:
765                 // user specific code here
766                 break;
767                 // GPIO interrupts are driven by an edge detection mechanism.  This
768                 // is latching so these interrupts must be acknowledged directly.
769                 // All other interrupts simply go away when the interrupting unit
770                 // has been serviced by the ISR.
771         case CYGNUM_HAL_INTERRUPT_GPIO1:
772                 HAL_WRITE_UINT32(GEDRx, 0x2);
773                 break;
774         case CYGNUM_HAL_INTERRUPT_GPIO0:
775                 HAL_WRITE_UINT32(GEDRx, 0x1);
776                 break;
777         default:                // the rest is second level GPIO
778                 if (vector >= CYGNUM_HAL_INTERRUPT_GPIO64) {
779                         HAL_WRITE_UINT32(GEDRz, (1 << (vector - 96)));
780                 } else if (vector >= CYGNUM_HAL_INTERRUPT_GPIO32) {
781                         HAL_WRITE_UINT32(GEDRy, (1 << (vector - 64)));
782                 } else if (vector >= CYGNUM_HAL_INTERRUPT_GPIO2) {
783                         HAL_WRITE_UINT32(GEDRx, (1 << (vector - 32)));
784                 }
785                 break;
786         }
787         return;
788 }
789
790 void hal_interrupt_configure(int vector, int level, int up)
791 {
792 #if DEBUG_INT
793         diag_printf("void hal_interrupt_configure(int vector, int level, int up) entered ...\n");
794         diag_printf("vector = %d    level = %d      up = %d   \n", vector, level, up);
795 #endif
796 #if 0
797 #ifdef HAL_EXTENDED_INTERRUPT_CONFIGURE
798         // Use platform specific handling, if defined
799         // Note: this macro should do a 'return' for "extended" values of 'vector'
800         // Normal vectors are handled by code subsequent to the macro call.
801         HAL_EXTENDED_INTERRUPT_CONFIGURE(vector, level, up);
802 #endif
803         if (vector >= CYGNUM_HAL_INTERRUPT_GPIO64) {
804                 if (level) {
805                         if (up) {
806                                 // Enable both edges
807                                 *(unsigned long*)GRERz |= (1 << (vector - 96));
808                                 *(unsigned long*)GFERz |= (1 << (vector - 96));
809                         } else {
810                                 // Disable both edges
811                                 *(unsigned long*)GRERz &= ~(1 << (vector - 96));
812                                 *(unsigned long*)GFERz &= ~(1 << (vector - 96));
813                         }
814                 } else {
815                         // Only interested in one edge
816                         if (up) {
817                                 // Set rising edge detect and clear falling edge detect.
818                                 *(unsigned long*)GRERz |= (1 << (vector - 96));
819                                 *(unsigned long*)GFERz &= ~(1 << (vector - 96));
820                         } else {
821                                 // Set falling edge detect and clear rising edge detect.
822                                 *(unsigned long*)GFERz |= (1 << (vector - 96));
823                                 *(unsigned long*)GRERz &= ~(1 << (vector - 96));
824                         }
825                 }
826         } else if (vector >= CYGNUM_HAL_INTERRUPT_GPIO32) {
827                 if (level) {
828                         if (up) {
829                                 // Enable both edges
830                                 *(unsigned long*)GRERy |= (1 << (vector - 64));
831                                 *(unsigned long*)GFERy |= (1 << (vector - 64));
832                         } else {
833                                 // Disable both edges
834                                 *(unsigned long*)GRERy &= ~(1 << (vector - 64));
835                                 *(unsigned long*)GFERy &= ~(1 << (vector - 64));
836                         }
837                 } else {
838                         // Only interested in one edge
839                         if (up) {
840                                 // Set rising edge detect and clear falling edge detect.
841                                 *(unsigned long*)GRERy |= (1 << (vector - 64));
842                                 *(unsigned long*)GFERy &= ~(1 << (vector - 64));
843                         } else {
844                                 // Set falling edge detect and clear rising edge detect.
845                                 *(unsigned long*)GFERy |= (1 << (vector - 64));
846                                 *(unsigned long*)GRERy &= ~(1 << (vector - 64));
847                         }
848                 }
849         } else if (vector >= CYGNUM_HAL_INTERRUPT_GPIO2) {
850                 if (level) {
851                         if (up) {
852                                 // Enable both edges
853                                 *(unsigned long*)GRERx |= (1 << (vector - 32));
854                                 *(unsigned long*)GFERx |= (1 << (vector - 32));
855                         } else {
856                                 // Disable both edges
857                                 *(unsigned long*)GRERx &= ~(1 << (vector - 32));
858                                 *(unsigned long*)GFERx &= ~(1 << (vector - 32));
859                         }
860                 } else {
861                         // Only interested in one edge
862                         if (up) {
863                                 // Set rising edge detect and clear falling edge detect.
864                                 *(unsigned long*)GRERx |= (1 << (vector - 32));
865                                 *(unsigned long*)GFERx &= ~(1 << (vector - 32));
866                         } else {
867                                 // Set falling edge detect and clear rising edge detect.
868                                 *(unsigned long*)GFERx |= (1 << (vector - 32));
869                                 *(unsigned long*)GRERx &= ~(1 << (vector - 32));
870                         }
871                 }
872         } else if (vector == CYGNUM_HAL_INTERRUPT_GPIO0 || vector == CYGNUM_HAL_INTERRUPT_GPIO1) {
873                 if (level) {
874                         if (up) {
875                                 // Enable both edges
876                                 *(unsigned long*)GRERx |= (1 << (vector - 8));
877                                 *(unsigned long*)GFERx |= (1 << (vector - 8));
878                         } else {
879                                 // Disable both edges
880                                 *(unsigned long*)GRERx &= ~(1 << (vector - 8));
881                                 *(unsigned long*)GFERx &= ~(1 << (vector - 8));
882                         }
883                 } else {
884                         // Only interested in one edge
885                         if (up) {
886                                 // Set rising edge detect and clear falling edge detect.
887                                 *(unsigned long*)GRERx |= (1 << (vector - 8));
888                                 *(unsigned long*)GFERx &= ~(1 << (vector - 8));
889                         } else {
890                                 // Set falling edge detect and clear rising edge detect.
891                                 *(unsigned long*)GFERx |= (1 << (vector - 8));
892                                 *(unsigned long*)GRERx &= ~(1 << (vector - 8));
893                         }
894                 }
895         }
896 #endif
897 }
898
899 void hal_interrupt_set_level(int vector, int level)
900 {
901 }
902
903 /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
904 /* Command and code to reset the hardware by issuing the reset vector      */
905 /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
906 void cyg_hal_xscale_soft_reset(CYG_ADDRESS entry)
907 {
908 #if 0
909         unsigned long oldints;
910
911         // clear reset status
912         HAL_WRITE_UINT32(RCSR, 0x0f);
913
914         HAL_DISABLE_INTERRUPTS(oldints);
915         HAL_DCACHE_SYNC();
916         HAL_ICACHE_DISABLE();
917         HAL_DCACHE_DISABLE();
918         HAL_DCACHE_SYNC();
919         HAL_ICACHE_INVALIDATE_ALL();
920         HAL_DCACHE_INVALIDATE_ALL();
921
922         asm volatile(
923                      "mcr p15,0,r0,c7,c10,4;"   //drain write buffer
924                      "mcr p15,0,r0,c7,c7,0;"    //invalidate I&D cache BTB
925                      "mrc p15,0,r0,c1,c0,0;"    //read ARM control register
926                      "bic r0,r0,#0xd;"          //disable data cache and mmu
927                      "bic r0,r0,#0x1000;"       //disable instruction cache
928                      "mcr p15,0,r0,c1,c0,0;"
929                      "mov pc,#0x0;"
930                      :
931                      :
932                      : "r0"
933                      );
934 #else
935         unsigned long value;
936
937         diag_printf("\nDoing software reset now");
938
939         // clear reset status
940         HAL_WRITE_UINT32(RCSR, 0x0f);
941
942         HAL_READ_UINT32(OSCR, value);
943         value += 325000;
944         HAL_WRITE_UINT32(OSMR3, value);
945         HAL_WRITE_UINT32(OWER, 1);
946         while (1) { // wait here for watchdog reset
947                 diag_printf(".");
948                 HAL_DELAY_US(10 * 1000);
949         }
950 #endif
951 }
952
953 void do_triton_reset(int argc, char *argv[])
954 {
955         HAL_PLATFORM_RESET();
956 }
957
958 RedBoot_cmd("reset",
959             "Reset the board/hardware",
960             "",
961             do_triton_reset
962             );
963
964 #ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
965 /*------------------------------------------------------------------------*/
966 //  HW Debug support
967
968 static inline void set_ibcr0(unsigned x)
969 {
970         asm volatile ("mcr p15,0,%0,c14,c8,0" : : "r"(x));
971 }
972
973 static inline unsigned get_ibcr0(void)
974 {
975         unsigned x;
976         asm volatile ("mrc p15,0,%0,c14,c8,0" : "=r"(x) :);
977         return x;
978 }
979
980 static inline void set_ibcr1(unsigned x)
981 {
982         asm volatile ("mcr p15,0,%0,c14,c9,0" : : "r"(x));
983 }
984
985 static inline unsigned get_ibcr1(void)
986 {
987         unsigned x;
988         asm volatile ("mrc p15,0,%0,c14,c9,0" : "=r"(x) :);
989         return x;
990 }
991
992 static inline void set_dbr0(unsigned x)
993 {
994         asm volatile ("mcr p15,0,%0,c14,c0,0" : : "r"(x));
995 }
996
997 static inline unsigned get_dbr0(void)
998 {
999         unsigned x;
1000         asm volatile ("mrc p15,0,%0,c14,c0,0" : "=r"(x) :);
1001         return x;
1002 }
1003
1004 static inline void set_dbr1(unsigned x)
1005 {
1006         asm volatile ("mcr p15,0,%0,c14,c3,0" : : "r"(x));
1007 }
1008
1009 static inline unsigned get_dbr1(void)
1010 {
1011         unsigned x;
1012         asm volatile ("mrc p15,0,%0,c14,c3,0" : "=r"(x) :);
1013         return x;
1014 }
1015
1016 static inline void set_dbcon(unsigned x)
1017 {
1018         asm volatile ("mcr p15,0,%0,c14,c4,0" : : "r"(x));
1019 }
1020
1021 static inline unsigned get_dbcon(void)
1022 {
1023         unsigned x;
1024         asm volatile ("mrc p15,0,%0,c14,c4,0" : "=r"(x) :);
1025         return x;
1026 }
1027
1028 static inline void set_dcsr(unsigned x)
1029 {
1030         asm volatile ("mcr p14,0,%0,c10,c0,0" : : "r"(x));
1031 }
1032
1033 static inline unsigned get_dcsr(void)
1034 {
1035         unsigned x;
1036         asm volatile ("mrc p14,0,%0,c10,c0,0" : "=r"(x) :);
1037         return x;
1038 }
1039
1040 int cyg_hal_plf_hw_breakpoint(int setflag, void *vaddr, int len)
1041 {
1042         unsigned int addr = (unsigned)vaddr;
1043
1044         if (setflag) {
1045                 if (!(get_ibcr0() & 1))
1046                         set_ibcr0(addr | 1);
1047                 else if (!(get_ibcr1() & 1))
1048                         set_ibcr1(addr | 1);
1049                 else
1050                         return -1;
1051         } else {
1052                 unsigned x = (addr | 1);
1053                 if (get_ibcr0() == x)
1054                         set_ibcr0(0);
1055                 else if (get_ibcr0() == x)
1056                         set_ibcr1(0);
1057                 else
1058                         return -1;
1059         }
1060         return 0;
1061 }
1062
1063 int cyg_hal_plf_hw_watchpoint(int setflag, void *vaddr, int len, int type)
1064 {
1065         unsigned int mask, bit_nr, mode, addr = (unsigned)vaddr;
1066         unsigned dbcon = get_dbcon();
1067
1068         mask = 0x80000000;
1069         bit_nr = 31;
1070         while (bit_nr) {
1071                 if (len & mask)
1072                         break;
1073                 bit_nr--;
1074                 mask >>= 1;
1075         }
1076         mask = ~(0xffffffff << bit_nr);
1077
1078         if (setflag) {
1079                 /* set a watchpoint */
1080                 if (type == 2)
1081                         mode = 1; // break on write
1082                 else if (type == 3)
1083                         mode = 3; // break on read
1084                 else if (type == 4)
1085                         mode = 2; // break on any access
1086                 else
1087                         return 1;
1088
1089                 if (!(dbcon & 3)) {
1090                         set_dbr0(addr);
1091                         set_dbr1(mask);
1092                         set_dbcon(dbcon | mode | 0x100);
1093                 } else
1094                         return 1;
1095         } else {
1096                 /* clear a watchpoint */
1097                 if (dbcon & 3)
1098                         set_dbcon(dbcon & ~3);
1099                 else
1100                         return 1;
1101         }
1102         return 0;
1103 }
1104
1105 // Return indication of whether or not we stopped because of a
1106 // watchpoint or hardware breakpoint. If stopped by a watchpoint,
1107 // also set '*data_addr_p' to the data address which triggered the
1108 // watchpoint.
1109 int cyg_hal_plf_is_stopped_by_hardware(void **data_addr_p)
1110 {
1111         unsigned fsr, dcsr, dbcon, kind = 0;
1112
1113         // Check for debug event
1114         asm volatile ("mrc p15,0,%0,c5,c0,0" : "=r"(fsr) :);
1115         if ((fsr & 0x200) == 0)
1116                 return HAL_STUB_HW_STOP_NONE;
1117
1118         // There was a debug event. Check the MOE for details
1119         dcsr = get_dcsr();
1120         switch ((dcsr >> 2) & 7) {
1121         case 1:  // HW breakpoint
1122                 return HAL_STUB_HW_STOP_BREAK;
1123         case 2:  // Watchpoint
1124                 dbcon = get_dbcon();
1125                 if (dbcon & 0x100) {
1126                         // dbr1 is used as address mask
1127                         kind = dbcon & 3;
1128                         *data_addr_p = (void *)get_dbr0();
1129                 }
1130                 if (kind == 1)
1131                         return HAL_STUB_HW_STOP_WATCH;
1132                 if (kind == 2)
1133                         return HAL_STUB_HW_STOP_AWATCH;
1134                 if (kind == 3)
1135                         return HAL_STUB_HW_STOP_RWATCH;
1136                 // should never get here
1137                 break;
1138         }
1139         return HAL_STUB_HW_STOP_NONE;
1140 }
1141 #endif // CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
1142
1143 #define SCL_LOW         (unsigned char)0x00
1144 #define SCL_HIGH        (unsigned char)0x01
1145 #define SDA_LOW         (unsigned char)0x00
1146 #define SDA_HIGH        (unsigned char)0x02
1147 #define I2C_WRITE       (unsigned char)0x00
1148 #define I2C_READ        (unsigned char)0x01
1149
1150 #define WRITE_REG32(__regadr, __val) ((__regadr) = (__val))
1151 #define READ_REG32(__regadr) (__regadr)
1152
1153 #define PXA250_AFREG_BASE       0x40e00054
1154 #define PXA250_PINDIR_BASE      0x40e0000c
1155 #define PXA250_PINSET_BASE      0x40e00018
1156 #define PXA250_PINCLEAR_BASE    0x40e00024
1157 #define PXA250_REDGE_BASE       0x40e00030
1158 #define PXA250_FEDGE_BASE       0x40e0003c
1159 #define PXA250_DEDGE_BASE       0x40e00048
1160 #define PXA250_PINLEVEL_BASE    0x40e00000
1161
1162 void pin_i2c_setup(pin_i2c_t *pin_data)
1163 {
1164         // configure pins as GPIO function
1165         set_alternate_function((unsigned char)pin_data->scl_no, 0);
1166         set_alternate_function((unsigned char)pin_data->sda_no, 0);
1167
1168         // set both pins to input
1169         set_pin_dir((unsigned char)pin_data->scl_no, 0);                /* 0=input 1=output */
1170         set_pin_dir((unsigned char)pin_data->sda_no, 0);                /* 0=input 1=output */
1171
1172         // clear all output registers
1173         clear_pin((unsigned char)pin_data->scl_no);
1174         clear_pin((unsigned char)pin_data->sda_no);
1175 }
1176
1177 void bus_out(pin_i2c_t *pin_data, unsigned char pdata)
1178 {
1179         switch (pdata & 0x03) {
1180         case 0:
1181                 set_pin_dir((unsigned char)pin_data->scl_no, 1);        /* 0=input 1=output */
1182                 set_pin_dir((unsigned char)pin_data->sda_no, 1);        /* 0=input 1=output */
1183                 break;
1184         case 1:
1185                 set_pin_dir((unsigned char)pin_data->scl_no, 0);        /* 0=input 1=output */
1186                 set_pin_dir((unsigned char)pin_data->sda_no, 1);        /* 0=input 1=output */
1187                 break;
1188         case 2:
1189                 set_pin_dir((unsigned char)pin_data->scl_no, 1);        /* 0=input 1=output */
1190                 set_pin_dir((unsigned char)pin_data->sda_no, 0);        /* 0=input 1=output */
1191                 break;
1192         case 3:
1193                 set_pin_dir((unsigned char)pin_data->scl_no, 0);        /* 0=input 1=output */
1194                 set_pin_dir((unsigned char)pin_data->sda_no, 0);        /* 0=input 1=output */
1195                 break;
1196         }
1197         return;
1198 }
1199
1200 int bus_in(pin_i2c_t *pin_data)
1201 {
1202         int result;
1203
1204         result = get_pin_status((unsigned char)pin_data->sda_no);
1205         if (result < 0) {
1206                 //dprintf("get_pin_status returned error \n");
1207                 return 1;
1208         } else {
1209                 return result;
1210         }
1211 }
1212
1213 void i2c_start(pin_i2c_t *pin_data)
1214 {
1215         //dprintf("pin status is %d\n", get_pin_status((unsigned char)pin_data->sda_no));
1216
1217         bus_out(pin_data, SCL_HIGH | SDA_LOW);
1218         HAL_DELAY_US(10);
1219
1220         bus_out(pin_data, SCL_HIGH | SDA_HIGH);
1221         HAL_DELAY_US(10);
1222
1223         bus_out(pin_data, SCL_HIGH | SDA_LOW);
1224         HAL_DELAY_US(10);
1225
1226         bus_out(pin_data, SCL_LOW | SDA_LOW);
1227         HAL_DELAY_US(10);
1228 }
1229
1230 void i2c_stop(pin_i2c_t *pin_data)
1231 {
1232         bus_out(pin_data, SCL_LOW | SDA_LOW);
1233         HAL_DELAY_US(10);
1234         bus_out(pin_data, SCL_HIGH | SDA_LOW);
1235         HAL_DELAY_US(10);
1236         bus_out(pin_data, SCL_HIGH | SDA_HIGH);
1237         HAL_DELAY_US(10);
1238 }
1239
1240 int i2c_read_ack(pin_i2c_t *pin_data)
1241 {
1242         bus_out(pin_data, SCL_LOW | SDA_HIGH);
1243         HAL_DELAY_US(10);
1244         bus_out(pin_data, SCL_HIGH | SDA_HIGH);
1245         HAL_DELAY_US(10);
1246         if (bus_in(pin_data)) {
1247                 bus_out(pin_data, SCL_LOW | SDA_HIGH);
1248                 HAL_DELAY_US(10);
1249                 return -2;
1250         } else {
1251                 bus_out(pin_data, SCL_LOW | SDA_HIGH);
1252                 HAL_DELAY_US(10);
1253                 return 0;
1254         }
1255 }
1256
1257 void i2c_write_ack(pin_i2c_t *pin_data)
1258 {
1259         bus_out(pin_data, SCL_LOW | SDA_LOW);
1260         HAL_DELAY_US(10);
1261         bus_out(pin_data, SCL_HIGH | SDA_LOW);
1262         HAL_DELAY_US(10);
1263         bus_out(pin_data, SCL_LOW | SDA_LOW);
1264         HAL_DELAY_US(10);
1265 }
1266
1267 void i2c_write_nack(pin_i2c_t *pin_data)
1268 {
1269         bus_out(pin_data, SCL_LOW | SDA_HIGH);
1270         HAL_DELAY_US(10);
1271         bus_out(pin_data, SCL_HIGH | SDA_HIGH);
1272         HAL_DELAY_US(10);
1273         bus_out(pin_data, SCL_LOW | SDA_HIGH);
1274         HAL_DELAY_US(10);
1275 }
1276
1277 void i2c_slave_addr(pin_i2c_t *pin_data, unsigned char dev, unsigned char mode)
1278 {
1279         i2c_write(pin_data, dev | mode);
1280 }
1281
1282 void i2c_read(pin_i2c_t *pin_data, unsigned char *res)
1283 {
1284         unsigned char in = 0;
1285         unsigned char bit = 0x80;
1286
1287         while (bit) {
1288                 bus_out(pin_data, SCL_LOW | SDA_HIGH);
1289                 HAL_DELAY_US(10);
1290                 bus_out(pin_data, SCL_HIGH | SDA_HIGH);
1291                 HAL_DELAY_US(10);
1292                 if (bus_in(pin_data))
1293                         in |= bit;
1294                 bus_out(pin_data, SCL_LOW | SDA_HIGH);
1295                 HAL_DELAY_US(10);
1296                 bit >>= 1;
1297         }
1298         *res = in;
1299 }
1300
1301 void i2c_write(pin_i2c_t *pin_data, unsigned char val)
1302 {
1303         unsigned char out;
1304         unsigned char bit = 0x80;
1305
1306         while (bit) {
1307                 out = (bit & val) ? SDA_HIGH : SDA_LOW;
1308                 bus_out(pin_data, SCL_LOW | out);
1309                 HAL_DELAY_US(10);
1310                 bus_out(pin_data, SCL_HIGH | out);
1311                 HAL_DELAY_US(10);
1312                 bus_out(pin_data, SCL_LOW | out);
1313                 HAL_DELAY_US(10);
1314                 bit >>= 1;
1315         }
1316 }
1317
1318 /* ================================================================ */
1319 /*
1320     function:   se_read
1321
1322     paramters:  unsigned char addr      start address in ser. EEPROM
1323                 unsigned int  numb      number of bytes to be read
1324                 char *dat               pointer to data buffer
1325
1326     ret. val.:  int                     = 0, every thing ok
1327                                           else, device not av., or not ready
1328
1329 */
1330 int se_read(pin_i2c_t *pin_data, unsigned char addr, unsigned char dev_address,
1331             unsigned int numb, char *dat)
1332 {
1333         unsigned int i;
1334
1335         i2c_start(pin_data);
1336         i2c_slave_addr(pin_data, dev_address, I2C_WRITE);
1337         if (i2c_read_ack(pin_data) < 0) {
1338                 i2c_stop(pin_data);
1339                 return -1;
1340         }
1341         i2c_write(pin_data, addr);        /* read from start address */
1342         if (i2c_read_ack(pin_data) < 0) {
1343                 i2c_stop(pin_data);
1344                 return -1;
1345         }
1346
1347         i2c_start(pin_data);
1348         i2c_slave_addr(pin_data, dev_address, I2C_READ);
1349         if (i2c_read_ack(pin_data) < 0) {
1350                 i2c_stop(pin_data);
1351                 return -1;
1352         }
1353
1354         for (i = 0; i < numb - 1; i++) {
1355                 i2c_read(pin_data, dat++);
1356                 i2c_write_ack(pin_data);
1357         }
1358         i2c_read(pin_data, dat);
1359         i2c_stop(pin_data);
1360
1361         return 0;
1362 }
1363
1364 /* ================================================================ */
1365 /*
1366     function:   se_write
1367
1368     paramters:  unsigned char addr      start address in ser. EEPROM
1369                 unsigned char val       value to write
1370
1371     ret. val.:  int                     = 0, every thing ok
1372                                           else, device not av., or not ready
1373
1374 */
1375 int se_write(pin_i2c_t *pin_data, unsigned char addr,unsigned char dev_address, unsigned char val)
1376 {
1377         i2c_start(pin_data);
1378         i2c_slave_addr(pin_data, dev_address, I2C_WRITE);
1379         if (i2c_read_ack(pin_data) < 0) {
1380                 i2c_stop(pin_data);
1381                 return -1;
1382         }
1383         i2c_write(pin_data, addr);
1384         if (i2c_read_ack(pin_data) < 0) {
1385                 i2c_stop(pin_data);
1386                 return -1;
1387         }
1388         i2c_write(pin_data, val);
1389         if (i2c_read_ack(pin_data) < 0) {
1390                 i2c_stop(pin_data);
1391                 return -1;
1392         }
1393         i2c_stop(pin_data);
1394         HAL_DELAY_US(10000);
1395         return 0;
1396 }
1397
1398 /* ================================================================ */
1399 /*
1400     function:   ltc1663_pwrite
1401
1402     paramters:  unsigned dev_address            device address of chip
1403                         unsigned char command           command byte
1404                 unsigned short val              value to write
1405
1406     ret. val.:  int                             = 0, every thing ok
1407                                                         else, device not av., or not ready
1408
1409 */
1410 int ltc1663_write(pin_i2c_t *pin_data, unsigned char dev_address, unsigned char command,
1411                   unsigned short val)
1412 {
1413         i2c_start(pin_data);
1414         i2c_slave_addr(pin_data, dev_address, I2C_WRITE);
1415         if (i2c_read_ack(pin_data) < 0) {
1416                 i2c_stop(pin_data);
1417                 return -1;
1418         }
1419         i2c_write(pin_data, command);
1420         if (i2c_read_ack(pin_data) < 0) {
1421                 i2c_stop(pin_data);
1422                 return -1;
1423         }
1424         i2c_write(pin_data, (unsigned char)val&0xff);
1425         if (i2c_read_ack(pin_data) < 0) {
1426                 i2c_stop(pin_data);
1427                 return -1;
1428         }
1429         i2c_write(pin_data, (unsigned char)((val&0xff00)>>8));
1430         if (i2c_read_ack(pin_data) < 0) {
1431                 i2c_stop(pin_data);
1432                 return -1;
1433         }
1434         i2c_stop(pin_data);
1435         HAL_DELAY_US(100);
1436         return 0;
1437 }
1438
1439 // -----------------------------------------------------------------------
1440 int set_alternate_function(unsigned char gpio_number, unsigned char function_code)
1441 {
1442         unsigned int register_offset;
1443         unsigned int bit_offset;
1444         unsigned long mask;
1445         unsigned long reg_adr;
1446         unsigned long org_value;
1447         unsigned long new_value;
1448
1449         // do some checking
1450         if (gpio_number >= NUM_GPIOS) {
1451                 //dprintf("GPIO pin number %d is out of range!\n", gpio_number);
1452                 return 0;
1453         }
1454
1455         if (function_code > 3) {
1456                 //dprintf("GPIO alternate function code %d is out of range\n", function_code);
1457                 return 0;
1458         }
1459
1460         register_offset = gpio_number / 16;
1461
1462         bit_offset = gpio_number % 16;
1463         mask = 3 << (bit_offset*2);
1464
1465         reg_adr = PXA250_AFREG_BASE + register_offset * 4;
1466
1467         org_value = READ_REG32(reg_adr);
1468
1469         new_value = (org_value & (~mask)) | (function_code << (bit_offset*2));
1470
1471         WRITE_REG32(reg_adr, new_value);
1472         return 1;
1473 }
1474
1475 int set_pin_dir(unsigned char gpio_number, unsigned char dir_code)
1476 {
1477         unsigned int register_offset;
1478         unsigned int bit_offset;
1479         unsigned long mask;
1480         unsigned long reg_adr;
1481         unsigned long org_value;
1482         unsigned long new_value;
1483
1484         // do some checking
1485         if (gpio_number >= NUM_GPIOS) {
1486                 //dprintf("GPIO pin number %d is out of range!\n", gpio_number);
1487                 return 0;
1488         }
1489
1490         if (dir_code > 1) {
1491                 //dprintf("GPIO alternate function code %d is out of range\n", dir_code);
1492                 return 0;
1493         }
1494
1495         register_offset = gpio_number / 32;
1496
1497         bit_offset = gpio_number % 32;
1498         mask = 1 << (bit_offset);
1499
1500         reg_adr = PXA250_PINDIR_BASE + register_offset * 4;
1501
1502         org_value = READ_REG32(reg_adr);
1503
1504         new_value = (org_value & (~mask)) | (dir_code << (bit_offset));
1505
1506         WRITE_REG32(reg_adr, new_value);
1507         return 1;
1508 }
1509
1510 int set_rising_edge(unsigned char gpio_number, unsigned char edge_code)
1511 {
1512         unsigned int register_offset;
1513         unsigned int bit_offset;
1514         unsigned long mask;
1515         unsigned long reg_adr;
1516         unsigned long org_value;
1517         unsigned long new_value;
1518
1519         // do some checking
1520         if (gpio_number >= NUM_GPIOS) {
1521                 //dprintf("GPIO pin number %d is out of range!\n", gpio_number);
1522                 return 0;
1523         }
1524         if (edge_code > 1) {
1525                 //dprintf("rising edge value sould be 0 or 1, not %d\n", edge_code);
1526                 return 0;
1527         }
1528         register_offset = gpio_number / 32;
1529
1530         bit_offset = gpio_number % 32;
1531         mask = 1 << (bit_offset);
1532
1533         reg_adr = PXA250_REDGE_BASE + register_offset * 4;
1534
1535         org_value = READ_REG32(reg_adr);
1536
1537         new_value = (org_value & (~mask)) | (edge_code << (bit_offset));
1538         WRITE_REG32(reg_adr, new_value);
1539         return 1;
1540 }
1541
1542 int set_falling_edge(unsigned char gpio_number, unsigned char edge_code)
1543 {
1544         unsigned int register_offset;
1545         unsigned int bit_offset;
1546         unsigned long mask;
1547         unsigned long reg_adr;
1548         unsigned long org_value;
1549         unsigned long new_value;
1550
1551         // do some checking
1552         if (gpio_number >= NUM_GPIOS) {
1553                 //dprintf("GPIO pin number %d is out of range!\n", gpio_number);
1554                 return 0;
1555         }
1556
1557         if (edge_code > 1) {
1558                 //dprintf("falling edge value sould be 0 or 1, not %d\n", edge_code);
1559                 return 0;
1560         }
1561
1562         register_offset = gpio_number / 32;
1563
1564         bit_offset = gpio_number % 32;
1565         mask = 1 << (bit_offset);
1566
1567         reg_adr = PXA250_FEDGE_BASE + register_offset * 4;
1568
1569         org_value = READ_REG32(reg_adr);
1570
1571         new_value = (org_value & (~mask)) | (edge_code << (bit_offset));
1572         WRITE_REG32(reg_adr, new_value);
1573         return 1;
1574 }
1575
1576 int set_pin(unsigned char gpio_number)
1577 {
1578         unsigned int register_offset;
1579         unsigned int bit_offset;
1580         unsigned long mask;
1581         unsigned long reg_adr;
1582         unsigned long org_value;
1583         unsigned long new_value;
1584
1585         // do some checking
1586         if (gpio_number >= NUM_GPIOS) {
1587                 //dprintf("GPIO pin number %d is out of range!\n", gpio_number);
1588                 return 0;
1589         }
1590
1591         register_offset = gpio_number / 32;
1592
1593         bit_offset = gpio_number % 32;
1594         mask = 1 << (bit_offset);
1595
1596         reg_adr = PXA250_PINSET_BASE + register_offset * 4;
1597
1598         org_value = 0;
1599
1600         new_value = (org_value & (~mask)) | (1 << (bit_offset));
1601
1602         WRITE_REG32(reg_adr, new_value);
1603         return 1;
1604
1605 }
1606
1607 int clear_pin(unsigned char gpio_number)
1608 {
1609         unsigned int register_offset;
1610         unsigned int bit_offset;
1611         unsigned long mask;
1612         unsigned long reg_adr;
1613         unsigned long org_value;
1614         unsigned long new_value;
1615
1616         // do some checking
1617         if (gpio_number >= NUM_GPIOS) {
1618                 //dprintf("GPIO pin number %d is out of range!\n", gpio_number);
1619                 return 0;
1620         }
1621
1622         register_offset = gpio_number / 32;
1623
1624         bit_offset = gpio_number % 32;
1625         mask = 1 << (bit_offset);
1626
1627         reg_adr = PXA250_PINCLEAR_BASE + register_offset * 4;
1628
1629         org_value = 0;
1630
1631         new_value = (org_value & (~mask)) | (1 << (bit_offset));
1632
1633         WRITE_REG32(reg_adr, new_value);
1634         return 1;
1635
1636 }
1637
1638 int get_pin_status(unsigned char gpio_number)
1639 {
1640         unsigned int register_offset;
1641         unsigned int bit_offset;
1642         unsigned long mask;
1643         unsigned long reg_adr;
1644         unsigned long return_value;
1645
1646         // do some checking
1647         if (gpio_number >= NUM_GPIOS) {
1648                 //dprintf("GPIO pin number %d is out of range!\n", gpio_number);
1649                 return -1;
1650         }
1651
1652         register_offset = gpio_number / 32;
1653
1654         bit_offset = gpio_number % 32;
1655         mask = 1 << (bit_offset);
1656
1657         reg_adr = PXA250_PINLEVEL_BASE + register_offset * 4;
1658
1659         return_value = (READ_REG32(reg_adr) & mask) >> bit_offset;
1660
1661         return return_value;
1662 }
1663
1664 int clear_edge(unsigned char gpio_number)
1665 {
1666         unsigned int register_offset;
1667         unsigned int bit_offset;
1668         unsigned long mask;
1669         unsigned long reg_adr;
1670         unsigned long org_value;
1671         unsigned long new_value;
1672
1673         // do some checking
1674         if (gpio_number >= NUM_GPIOS) {
1675                 //dprintf("GPIO pin number %d is out of range!\n", gpio_number);
1676                 return 0;
1677         }
1678
1679         register_offset = gpio_number / 32;
1680
1681         bit_offset = gpio_number % 32;
1682         mask = 1 << (bit_offset);
1683
1684         reg_adr = PXA250_DEDGE_BASE + register_offset * 4;
1685
1686         org_value = READ_REG32(reg_adr);
1687
1688         new_value = (org_value & (~mask)) | (1 << (bit_offset));
1689         WRITE_REG32(reg_adr, new_value);
1690
1691         return 1;
1692 }
1693
1694 int detect_edge(unsigned char gpio_number)
1695 {
1696         unsigned int register_offset;
1697         unsigned int bit_offset;
1698         unsigned long mask;
1699         unsigned long reg_adr;
1700         unsigned long org_value;
1701
1702         // do some checking
1703         if (gpio_number >= NUM_GPIOS) {
1704                 //dprintf("GPIO pin number %d is out of range!\n", gpio_number);
1705                 return 0;
1706         }
1707
1708         register_offset = gpio_number / 32;
1709
1710         bit_offset = gpio_number % 32;
1711         mask = 1 << (bit_offset);
1712
1713         reg_adr = PXA250_DEDGE_BASE + register_offset * 4;
1714
1715         org_value = READ_REG32(reg_adr);
1716
1717         return !!(org_value & mask);
1718 }
1719
1720 void init_i2c(void)
1721 {
1722         HAL_WRITE_UINT32(ICR, ICR_UR);                          // reset i2c_unit;
1723         HAL_WRITE_UINT32(ICR, ICR_IUE | ICR_SCLE | ICR_GCD);
1724 }
1725
1726 //FIXME: insert timeout into while loop
1727 cyg_int32 write_i2c_pcf8574(cyg_uint8 device_adr,  cyg_uint8 dat_value)
1728 {
1729         cyg_uint32      value;
1730         unsigned int    retries;
1731
1732 // write device address now
1733         HAL_WRITE_UINT32(IDBR, (device_adr & 0xfe));
1734         HAL_READ_UINT32(ICR, value);
1735         value = value & ~(ICR_STOP | ICR_ALDIE);
1736         HAL_WRITE_UINT32(ICR, value | ICR_START | ICR_TB);
1737
1738         HAL_READ_UINT32(ISR, value);
1739         value &= ISR_ITE;
1740         while (!value) {        // wait for Transmit Empty
1741                 HAL_READ_UINT32(ISR, value);
1742                 value &= ISR_ITE;
1743         }
1744         HAL_READ_UINT32(ISR, value);
1745         if (value & ISR_BED) {
1746
1747                 //diag_printf("I2C: bus error, status after write device address is: %06X\n", value);
1748                 HAL_READ_UINT32(ICR, value);
1749                 HAL_WRITE_UINT32(ICR, value | ICR_MA);          // send master abort
1750                 HAL_DELAY_US(10000);
1751                 HAL_WRITE_UINT32(ICR, value & ~ICR_MA);
1752                 return -1;
1753         }
1754         HAL_WRITE_UINT32(ISR, ISR_ITE); // clear ITE status
1755
1756 // write data now
1757         HAL_WRITE_UINT32(IDBR, (dat_value & 0xff));
1758         HAL_READ_UINT32(ICR, value);
1759         value &=  ~ICR_START;
1760         HAL_WRITE_UINT32(ICR, value | ICR_TB | ICR_STOP);
1761
1762         HAL_READ_UINT32(ISR, value);
1763         retries = 1000000;
1764         while (!(value & ISR_ITE)) {    // wait for Transmit Empty
1765                 HAL_READ_UINT32(ISR, value);
1766         }
1767         if (!(value & ISR_ITE)) {
1768                 diag_printf("I2C: timeout waiting for ITE\n");
1769                 return -1;
1770         }
1771         if (value & ISR_BED) {
1772                 //diag_printf("I2C: bus error, status after write device address is: %06X\n", value);
1773                 HAL_READ_UINT32(ICR, value);
1774                 HAL_WRITE_UINT32(ICR, value | ICR_MA);          // send master abort
1775                 HAL_DELAY_US(10000);
1776                 HAL_WRITE_UINT32(ICR, value & ~ICR_MA);
1777                 return -1;
1778         }
1779         HAL_WRITE_UINT32(ISR, ISR_ITE); // clear ITE status
1780
1781         HAL_READ_UINT32(ICR, value);
1782         value = value  &  ~(ICR_STOP | ICR_START | ICR_TB);
1783         HAL_WRITE_UINT32(ICR, value);
1784
1785         return 0;
1786 }
1787
1788 //FIXME: insert timeout into while loop
1789 cyg_int32 read_i2c_pcf8574(cyg_uint8 device_adr)
1790 {
1791         cyg_uint32      value;
1792         unsigned int    retries;
1793
1794         // write device address now
1795         HAL_WRITE_UINT32(IDBR, (device_adr | 0x01));
1796
1797         HAL_READ_UINT32(ICR, value);
1798         value &= ~ICR_STOP;
1799         HAL_WRITE_UINT32(ICR, value | ICR_START | ICR_TB);
1800
1801         HAL_READ_UINT32(ISR, value);
1802         retries = 1000000;
1803         while (!(value & ISR_ITE)) {    // wait for Transmit Empty
1804                 HAL_READ_UINT32(ISR, value);
1805         }
1806         if (!(value & ISR_ITE)) {
1807                 diag_printf("I2C: timeout waiting for ITE\n");
1808                 return -1;
1809         }
1810         if (value & ISR_BED) {
1811                 //diag_printf("I2C: bus error, status after write device address is: %06X\n", value);
1812                 HAL_READ_UINT32(ICR, value);
1813                 HAL_WRITE_UINT32(ICR, value | ICR_MA);          // send master abort
1814                 HAL_DELAY_US(10000);
1815                 HAL_WRITE_UINT32(ICR, value & ~ICR_MA);
1816                 return -1;
1817         }
1818         HAL_WRITE_UINT32(ISR, ISR_ITE); // clear ITE status
1819
1820         // read data now
1821         HAL_READ_UINT32(ICR, value);
1822         value &= ~ICR_START;
1823         HAL_WRITE_UINT32(ICR,  value |ICR_TB | ICR_STOP | ICR_ACKNAK);
1824
1825         HAL_READ_UINT32(ISR, value);
1826         value &= ISR_IRF;
1827         while (!value) {        // wait for Receive Buffer full
1828                 HAL_READ_UINT32(ISR, value);
1829                 value &= ISR_IRF;
1830         }
1831
1832         HAL_WRITE_UINT32(ISR, ISR_IRF); // clear ITE status
1833
1834         HAL_READ_UINT32(ICR, value);
1835         value = value & ~(ICR_STOP | ICR_START | ICR_TB | ICR_ACKNAK);
1836         HAL_WRITE_UINT32(ICR, value);
1837
1838         HAL_READ_UINT32(IDBR, value);
1839
1840         return value & 0xff;
1841 }
1842 /*------------------------------------------------------------------------*/
1843 // EOF triton_misc.c