1 //==========================================================================
5 // KaRo TRITON270 [platform] specific RedBoot commands
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.
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.
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.
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.
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.
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.
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####
44 // Contributors: gthomas
45 // Richard Panton <richard.panton@3glab.com>
50 // This code is part of RedBoot (tm).
52 //####DESCRIPTIONEND####
54 //==========================================================================
58 #include <cyg/hal/hal_triton270.h>
59 #include <cyg/hal/hal_intr.h>
60 #include <cyg/hal/hal_cache.h>
62 #include <cyg/hal/hal_io.h> // IO macros
65 "Set a memory location",
66 "[-h|-b] [-a <address>] <data>",
70 void do_mem(int argc, char *argv[])
72 struct option_info opts[3];
73 bool mem_half_word, mem_byte;
74 volatile cyg_uint32 *address = NULL;
77 init_opts(&opts[0], 'b', false, OPTION_ARG_TYPE_FLG,
78 (void *)&mem_byte, 0, "write a byte");
79 init_opts(&opts[1], 'h', false, OPTION_ARG_TYPE_FLG,
80 (void *)&mem_half_word, 0, "write a half-word");
81 init_opts(&opts[2], 'a', true, OPTION_ARG_TYPE_NUM,
82 (void *)&address, NULL, "address to write at");
83 if (!scan_opts(argc, argv, 1, opts, 3, (void*)&value, OPTION_ARG_TYPE_NUM, "address to set"))
85 if (mem_byte && mem_half_word) {
86 diag_printf("*ERR: Should not specify both byte and half-word access\n");
87 } else if (mem_byte) {
88 *(cyg_uint8*)address = (cyg_uint8)(value & 255);
89 diag_printf(" Set 0x%08X to 0x%02X (result 0x%02X)\n", address, value & 255, (int)*(cyg_uint8*)address);
90 } else if (mem_half_word) {
91 if ((unsigned long)address & 1) {
92 diag_printf("*ERR: Badly aligned address 0x%08X for half-word store\n", address);
94 *(cyg_uint16*)address = (cyg_uint16)(value & 0xffff);
95 diag_printf(" Set 0x%08X to 0x%04X (result 0x%04X)\n", address, value & 0xffff, (int)*(cyg_uint16*)address);
98 if ((unsigned long)address & 3) {
99 diag_printf("*ERR: Badly aligned address 0x%08X for word store\n", address);
102 diag_printf(" Set 0x%08X to 0x%08X (result 0x%08X)\n", address, value,
109 "Set/Query the system clock speed",
110 "[-s <clock> (200/300/400/500/600)]",
114 clock_param_t pclktab[] = {
115 {91, 45, 91, 45, 91, 0, 7, 2, 0, 0, 0, 950, 0x02, 1, 1},
116 {104, 104, 104, 104, 52, 1, 8, 2, 1, 0, 1, 950, 0x02, 0, 1},
117 {156, 104, 104, 104, 52, 1, 8, 6, 1, 1, 1, 1150, 0x06, 0, 1},
118 {208, 208, 208, 104, 104, 1, 16, 2, 1, 0, 1, 1150, 0x06, 1, 1},
119 {312, 208, 208, 104, 104, 1, 16, 3, 1, 0, 1, 1250, 0x08, 1, 1},
120 {416, 208, 208, 104, 104, 1, 16, 4, 1, 0, 1, 1350, 0x0a, 1, 1},
121 {520, 208, 208, 104, 104, 1, 16, 5, 1, 0, 1, 1450, 0x0c, 1, 1},
122 {624, 208, 208, 104, 104, 1, 16, 6, 1, 0, 1, 1550, 0x0e, 1, 1},
124 clock_param_t *get_clock_rate(void);
126 int get_clock_table_index(int clock)
134 maxindex = sizeof(pclktab) / sizeof(clock_param_t) - 1;
135 if (clock < pclktab[0].t_clock) {
138 } else if (clock > pclktab[maxindex].t_clock) {
142 while (i <= maxindex) {
143 if (pclktab[i].t_clock < clock) {
149 deltan = pclktab[i].t_clock - clock;
150 deltap = pclktab[i + 1].t_clock - clock;
151 if (deltan < deltap) {
165 void change_core_voltage(unsigned char ind)
170 HAL_READ_UINT32(PCFR, value);
172 HAL_WRITE_UINT32(PCFR, value);
174 diag_printf("Core voltage will be set to %d.%d Volts",
175 pclktab[ind].VOLTAGE_VAL / 1000, pclktab[ind].VOLTAGE_VAL % 1000);
176 write_i2c_pwr(0x18, pclktab[ind].DAC_VAL | 0x20);
180 HAL_READ_UINT32(PCFR, value);
182 HAL_WRITE_UINT32(PCFR, value);
185 clock_param_t *get_clock_rate(void)
187 unsigned long CCCR_reg, CLKCFG_reg;
188 unsigned char clkcfg_t, clkcfg_ht, clkcfg_b;
189 unsigned char cccr_l, cccr_2n, cccr_a;
191 clock_param_t *match = NULL;
194 "ldr r1, =0x41300000;" // Core Clock Config Reg
196 "mrc p14, 0, %1, c6, c0, 0;" // read CCLKCFG register
197 : "=r"(CCCR_reg), "=r"(CLKCFG_reg)
202 clkcfg_t = CLKCFG_reg & 0x01;
203 clkcfg_ht = (CLKCFG_reg & 0x04) >> 2;
204 clkcfg_b = (CLKCFG_reg & 0x08) >> 3;
206 cccr_l = (CCCR_reg & 0x0000001f) >> 0;
207 cccr_2n = (CCCR_reg & 0x00000780) >> 7;
208 cccr_a = (CCCR_reg & 0x02000000) >> 25;
210 diag_printf("clkcfg_t = %d \n", clkcfg_t);
211 diag_printf("clkcfg_ht = %d \n", clkcfg_ht);
212 diag_printf("clkcfg_b = %d \n", clkcfg_b);
213 diag_printf("cccr_l = %d \n", cccr_l);
214 diag_printf("cccr_2n = %d \n", cccr_2n);
215 diag_printf("cccr_a = %d \n", cccr_a);
217 for (i = 0; i < sizeof(pclktab) / sizeof(clock_param_t); i++) {
218 if (clkcfg_t == pclktab[i].CLKCFG_T &&
219 clkcfg_ht == pclktab[i].CLKCFG_HT &&
220 clkcfg_b == pclktab[i].CLKCFG_B &&
221 cccr_l == pclktab[i].CCCR_L &&
222 cccr_2n == pclktab[i].CCCR_2N &&
223 cccr_a == pclktab[i].CCCR_A) {
230 //diag_printf("error, unknown clock configuration\n");
235 void change_clock(unsigned char ind)
237 clock_param_t *cpara;
238 unsigned long CCCR_reg, CLKCFG_reg;
240 diag_printf("Clock speed will be changed to %d MHz", pclktab[ind].t_clock);
241 CCCR_reg = pclktab[ind].CCCR_L |
242 ((pclktab[ind].CCCR_2N) << 7) |
243 ((pclktab[ind].CCCR_A) << 25);
244 CLKCFG_reg = pclktab[ind].CLKCFG_T |
245 ((pclktab[ind].CLKCFG_HT) << 2) |
246 ((pclktab[ind].CLKCFG_B) << 3);
249 "ldr r2, =0x41300000;" // Core Clock Config Reg
250 "ldr r3, [r2];" // read the register
251 "ldr r4, =0xcc000000;" // mask bits to preserve
253 "orr r3, r3, r1;" // write speed values
254 "str r3, [r2];" // set speed
255 "mov r1, %1;" // set turbo mode, set fast bus
256 "orr r1, r1, #0x2;" // set change frequency
257 "mov r3, r1;" // save value
258 "mcr p14, 0, r1, c6, c0, 0;" // frequency change sequence
259 "ldr r1, [r2];" // dummy read from CCCR
261 "mrc p14, 0, r1, c6, c0, 0;" // read CLKCFG
262 "cmp r3, r1;" // compare it with value written
265 : "r"(CCCR_reg), "r"(CLKCFG_reg)
266 : "r1", "r2", "r3", "r4"
268 cpara = get_clock_rate();
269 diag_printf("\nclock speed set to %d MHz ...\n", cpara->t_clock);
272 void do_clock(int argc, char *argv[])
275 bool new_clock_set, clock_ok;
276 struct option_info opts[1];
277 //#ifdef CYGSEM_REDBOOT_FLASH_CONFIG
278 // struct config_option opt;
281 clock_param_t *cpara, *old_clock;
283 init_opts(&opts[0], 's', true, OPTION_ARG_TYPE_NUM,
284 (void *)&new_clock, (bool *)&new_clock_set, "new clock speed");
285 if (!scan_opts(argc, argv, 1, opts, 1, 0, 0, "")) {
289 get_clock_table_index(new_clock);
294 old_clock = get_clock_rate();
295 if (old_clock == 0) {
296 diag_printf("error decoding clock settings, clock unknown\n");
299 ind = get_clock_table_index(new_clock);
301 HAL_READ_UINT32(MDREFR, value);
302 value |= 0x20000000; // set K0DB4
303 HAL_WRITE_UINT32(MDREFR, value);
305 if (pclktab[ind].t_clock > old_clock->t_clock) {
306 change_core_voltage(ind);
310 change_core_voltage(ind);
313 if (pclktab[ind].MDREFR_K0DB2) {
314 HAL_READ_UINT32(MDREFR, value); // set K0DB2
317 HAL_READ_UINT32(MDREFR, value); // reset K0DB0
318 value &= (~0x00004000);
320 HAL_WRITE_UINT32(MDREFR, value);
322 if (pclktab[ind].MDREFR_K0DB4) {
323 HAL_READ_UINT32(MDREFR, value); // set K0DB2
326 HAL_READ_UINT32(MDREFR, value); // reset K0DB2
327 value &= (~0x20000000);
329 HAL_WRITE_UINT32(MDREFR, value);
331 cpara = get_clock_rate();
333 diag_printf("error decoding clock settings, clock unknown\n");
335 diag_printf("Actual Processor Clock: %d MHz System Bus Clock %d MHz MEM Clock %d MHz SDRAM Clock %d MHz LCD Clock %d MHz\n",
336 cpara->t_clock, cpara->sys_clock, cpara->mem_clock, cpara->SDRAM_clock, cpara->LCD_clock);
342 "Execute code at a location",
343 "[-w <timeout>] [entry]",
347 void do_run(int argc, char *argv[])
349 typedef void code_fun(void);
351 unsigned long oldints;
355 struct option_info opts[1];
358 entry = entry_address; // Default from last 'load' operation
359 init_opts(&opts[0], 'w', true, OPTION_ARG_TYPE_NUM,
360 (void *)&wait_time, (bool *)&wait_time_set, "wait timeout");
361 if (!scan_opts(argc, argv, 1, opts, 1, (void *)&entry, OPTION_ARG_TYPE_NUM,
362 "starting address")) {
364 diag_printf("starting run at address 0x%08X ...\n", entry);
367 int script_timeout_ms = wait_time * 1000;
368 #ifdef CYGSEM_REDBOOT_FLASH_CONFIG
369 unsigned char *hold_script = script;
370 script = (unsigned char *)0;
372 diag_printf("About to start execution at %p - abort with ^C within %d seconds\n",
373 (void *)entry, wait_time);
374 while (script_timeout_ms >= CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT) {
375 res = _rb_gets(line, sizeof(line), CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT);
376 if (res == _GETS_CTRLC) {
377 #ifdef CYGSEM_REDBOOT_FLASH_CONFIG
378 script = hold_script; // Re-enable script
382 script_timeout_ms -= CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT;
385 fun = (code_fun *)entry;
386 HAL_DISABLE_INTERRUPTS(oldints);
388 HAL_ICACHE_DISABLE();
389 HAL_DCACHE_DISABLE();
391 HAL_ICACHE_INVALIDATE_ALL();
392 HAL_DCACHE_INVALIDATE_ALL();
393 #ifdef HAL_ARCH_PROGRAM_NEW_STACK
394 HAL_ARCH_PROGRAM_NEW_STACK(fun);
400 HAL_RESTORE_INTERRUPTS(oldints);
403 cyg_int32 write_i2c_pwr(cyg_uint8 device_adr, cyg_uint8 dat_value)
406 unsigned int retries;
408 // write device address now
410 HAL_WRITE_UINT32(PWRIDBR, (device_adr & 0xfe));
411 HAL_READ_UINT32(PWRICR, value);
412 value = value & ~(ICR_STOP | ICR_ALDIE);
413 HAL_WRITE_UINT32(PWRICR, value | ICR_START | ICR_TB);
415 HAL_READ_UINT32(PWRISR, value);
417 while (!(value & ISR_ITE) && retries--) { // wait for Transmit Empty
418 HAL_READ_UINT32(PWRISR, value);
420 if (!(value & ISR_ITE)) {
421 diag_printf("I2C: timeout waiting for ITE\n");
425 HAL_READ_UINT32(PWRISR, value);
426 if (value & ISR_BED) {
427 //diag_printf("I2C: bus error, status after write device address is: %06X\n", value);
428 HAL_READ_UINT32(PWRICR, value);
429 HAL_WRITE_UINT32(PWRICR, value | ICR_MA); // send master abort
431 HAL_WRITE_UINT32(PWRICR, value & ~ICR_MA);
434 HAL_WRITE_UINT32(PWRISR, ISR_ITE); // clear ITE status
437 HAL_WRITE_UINT32(PWRIDBR, dat_value & 0xff);
438 HAL_READ_UINT32(PWRICR, value);
440 HAL_WRITE_UINT32(PWRICR, value | (ICR_TB | ICR_STOP));
442 HAL_READ_UINT32(PWRISR, value);
444 while (!(value & ISR_ITE) && retries--) { // wait for Transmit Empty
445 HAL_READ_UINT32(PWRISR, value);
447 if (!(value & ISR_ITE)) {
448 diag_printf("I2C: timeout waiting for ITE\n");
451 HAL_READ_UINT32(PWRISR, value);
452 if (value & ISR_BED) {
453 //diag_printf("I2C: bus error, status after write device address is: %06X\n", value);
454 HAL_READ_UINT32(PWRICR, value);
455 HAL_WRITE_UINT32(PWRICR, value | ICR_MA); // send master abort
457 HAL_WRITE_UINT32(PWRICR, value & ~ICR_MA);
460 HAL_WRITE_UINT32(PWRISR, ISR_ITE); // clear ITE status
462 HAL_READ_UINT32(PWRICR, value);
463 value = value & ~(ICR_STOP | ICR_START | ICR_TB);
464 HAL_WRITE_UINT32(PWRICR, value);