3 * Piotr Dymacz (pepe2k), Real Time Systems, piotr@realtimesystems.pl, pepe2k@gmail.com
4 * Custom commands for U-Boot 1.1.4 modification.
6 * See file CREDITS for list of people who contributed to U-Boot project.
8 * This program is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
24 #include <asm/mipsregs.h>
25 #include <asm/addrspace.h>
26 #include <ar7240_soc.h>
27 #include "../board/ar7240/common/ar7240_flash.h"
29 extern void ar7240_sys_frequency(u32 *cpu_freq, u32 *ddr_freq, u32 *ahb_freq);
31 #if defined(OFFSET_MAC_ADDRESS)
33 * Show MAC address(es)
35 int do_print_mac(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]){
37 #if defined(OFFSET_MAC_ADDRESS2)
41 #if defined(OFFSET_MAC_ADDRESS2)
42 // get MAC1 and MAC2 addresses from flash and print them
43 memcpy(buffer, (void *)(CFG_FLASH_BASE + OFFSET_MAC_DATA_BLOCK + OFFSET_MAC_ADDRESS), 6);
44 memcpy(buffer2, (void *)(CFG_FLASH_BASE + OFFSET_MAC_DATA_BLOCK + OFFSET_MAC_ADDRESS2), 6);
46 puts("Current MAC addresses stored in flash:\n");
47 printf("MAC1 at 0x%X: %02X:%02X:%02X:%02X:%02X:%02X\n", CFG_FLASH_BASE + OFFSET_MAC_DATA_BLOCK + OFFSET_MAC_ADDRESS,
48 buffer[0] & 0xFF, buffer[1] & 0xFF, buffer[2] & 0xFF, buffer[3] & 0xFF, buffer[4] & 0xFF, buffer[5] & 0xFF);
50 printf("MAC2 at 0x%X: %02X:%02X:%02X:%02X:%02X:%02X\n\n", CFG_FLASH_BASE + OFFSET_MAC_DATA_BLOCK + OFFSET_MAC_ADDRESS2,
51 buffer2[0] & 0xFF, buffer2[1] & 0xFF, buffer2[2] & 0xFF, buffer2[3] & 0xFF, buffer2[4] & 0xFF, buffer2[5] & 0xFF);
53 // get MAC address from flash and print it
54 memcpy(buffer, (void *)(CFG_FLASH_BASE + OFFSET_MAC_DATA_BLOCK + OFFSET_MAC_ADDRESS), 6);
56 printf("Current MAC address stored in flash at offset 0x%X: ", CFG_FLASH_BASE + OFFSET_MAC_DATA_BLOCK + OFFSET_MAC_ADDRESS);
57 printf("%02X:%02X:%02X:%02X:%02X:%02X\n\n", buffer[0] & 0xFF, buffer[1] & 0xFF, buffer[2] & 0xFF, buffer[3] & 0xFF, buffer[4] & 0xFF, buffer[5] & 0xFF);
63 #if defined(OFFSET_MAC_ADDRESS2)
64 U_BOOT_CMD(printmac, 1, 1, do_print_mac, "print MAC addresses stored in flash\n", NULL);
66 U_BOOT_CMD(printmac, 1, 1, do_print_mac, "print MAC address stored in flash\n", NULL);
70 * Change MAC address(es)
72 int do_set_mac(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]){
73 unsigned char *data_pointer;
77 // allow only 2 arg (command name + mac), second argument length should be 17 (xx:xx:xx:xx:xx:xx)
78 if(argc != 2 || strlen(argv[1]) != 17){
79 #if defined(CFG_LONGHELP)
80 if(cmdtp->help != NULL){
81 printf("Usage:\n%s %s\n", cmdtp->name, cmdtp->help);
83 printf("Usage:\n%s %s\n", cmdtp->name, cmdtp->usage);
86 printf("Usage:\n%s %s\n", cmdtp->name, cmdtp->usage);
92 for(i = 0; i< 17; i++){
93 if(argv[1][i] == ':'){
99 puts("## Error: given MAC address has wrong format (should be: xx:xx:xx:xx:xx:xx)!\n");
103 // backup block with MAC address from flash in RAM
104 data_pointer = (unsigned char *)WEBFAILSAFE_UPLOAD_RAM_ADDRESS;
107 puts("## Error: couldn't allocate RAM for data block backup!\n");
111 puts("** Notice:\n you should always make a backup of your device\n entire FLASH content before making any changes\n\n");
113 memcpy((void *)data_pointer, (void *)(CFG_FLASH_BASE + OFFSET_MAC_DATA_BLOCK), OFFSET_MAC_DATA_BLOCK_LENGTH);
115 // store new MAC address in RAM
116 for(i = 0; i < 6; i++){
117 data_pointer[OFFSET_MAC_ADDRESS + i] = simple_strtoul((char *)(argv[1] + i*3), NULL, 16);
120 // now we can erase flash and write data from RAM
122 "erase 0x%lX +0x%lX; cp.b 0x%lX 0x%lX 0x%lX",
123 CFG_FLASH_BASE + OFFSET_MAC_DATA_BLOCK,
124 OFFSET_MAC_DATA_BLOCK_LENGTH,
125 WEBFAILSAFE_UPLOAD_RAM_ADDRESS,
126 CFG_FLASH_BASE + OFFSET_MAC_DATA_BLOCK,
127 OFFSET_MAC_DATA_BLOCK_LENGTH);
129 printf("Executing: %s\n\n", buf);
131 return(run_command(buf, 0));
134 U_BOOT_CMD(setmac, 2, 0, do_set_mac, "save new MAC address in flash\n", "xx:xx:xx:xx:xx:xx\n\t- change MAC address stored in flash (xx - value in hex format)\n");
136 #endif /* if defined(OFFSET_MAC_ADDRESS) */
138 #if defined(OFFSET_ROUTER_MODEL)
140 * Show TP-Link router model
142 int do_print_model(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]){
143 unsigned char buffer[8];
145 // get router model from flash and print it
146 memcpy(buffer, (void *)(CFG_FLASH_BASE + OFFSET_MAC_DATA_BLOCK + OFFSET_ROUTER_MODEL), 8);
148 printf("Router model stored in flash at offset 0x%X: ", CFG_FLASH_BASE + OFFSET_MAC_DATA_BLOCK + OFFSET_ROUTER_MODEL);
149 printf("%02X%02X%02X%02X%02X%02X%02X%02X\n\n", buffer[0] & 0xFF, buffer[1] & 0xFF, buffer[2] & 0xFF, buffer[3] & 0xFF, buffer[4] & 0xFF, buffer[5] & 0xFF, buffer[6] & 0xFF, buffer[7] & 0xFF);
154 U_BOOT_CMD(printmodel, 1, 1, do_print_model, "print router model stored in flash\n", NULL);
156 #endif /* if defined(OFFSET_ROUTER_MODEL) */
158 #if defined(OFFSET_PIN_NUMBER)
162 int do_print_pin(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]){
163 unsigned char buffer[9];
165 // get pin number from flash and print it
166 memcpy(buffer, (void *)(CFG_FLASH_BASE + OFFSET_MAC_DATA_BLOCK + OFFSET_PIN_NUMBER), 8);
169 printf("Router pin number stored in flash at offset 0x%X: ", CFG_FLASH_BASE + OFFSET_MAC_DATA_BLOCK + OFFSET_PIN_NUMBER);
170 printf("%s\n\n", buffer);
175 U_BOOT_CMD(printpin, 1, 1, do_print_pin, "print WPS pin stored in flash\n", NULL);
177 #endif /* if defined(OFFSET_PIN_NUMBER) */
179 #if defined(CONFIG_NETCONSOLE)
183 int do_start_nc(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]){
184 return(run_command("setenv stdin nc;setenv stdout nc;setenv stderr nc;version;", 0));
187 U_BOOT_CMD(startnc, 1, 0, do_start_nc, "start net console\n", NULL);
190 * Start Serial Console
192 int do_start_sc(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]){
193 return(run_command("setenv stdin serial;setenv stdout serial;setenv stderr serial;version;", 0));
196 U_BOOT_CMD(startsc, 1, 0, do_start_sc, "start serial console\n", NULL);
198 #endif /* if defined(CONFIG_NETCONSOLE) */
200 #if defined(CONFIG_FOR_8DEVICES_CARAMBOLA2) || \
201 defined(CONFIG_FOR_DRAGINO_V2)
203 * Erase environment sector
205 int do_erase_env(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]){
209 "erase 0x%lX +0x%lX",
213 printf("Executing: %s\n\n", buf);
215 return(run_command(buf, 0));
218 U_BOOT_CMD(eraseenv, 1, 1, do_erase_env, "erase environment sector in flash\n", NULL);
219 #endif /* if defined(CONFIG_FOR_8DEVICES_CARAMBOLA2) || defined(CONFIG_FOR_DRAGINO_V2) */
221 #if defined(PLL_IN_FLASH_MAGIC_OFFSET)
225 unsigned short cpu_clock;
226 unsigned short ram_clock;
227 unsigned short ahb_clock;
228 unsigned short spi_clock;
231 // (more info in includes/configs/ap121.h)
232 unsigned int cpu_clk_control;
233 unsigned int cpu_pll_config;
234 unsigned int spi_control;
235 } ar9331_clock_profile;
237 static const ar9331_clock_profile oc_profiles[] = {
240 MAKE_AR9331_CPU_CLK_CONTROL_VAL(1, 1, 2),
241 #if defined(CONFIG_40MHZ_XTAL_SUPPORT)
242 MAKE_AR9331_CPU_PLL_CONFIG_VAL(20, 1, 0, 2),
244 MAKE_AR9331_CPU_PLL_CONFIG_VAL(32, 1, 0, 2),
246 MAKE_AR9331_SPI_CONTROL_VAL(4)
251 MAKE_AR9331_CPU_CLK_CONTROL_VAL(1, 1, 1),
252 #if defined(CONFIG_40MHZ_XTAL_SUPPORT)
253 MAKE_AR9331_CPU_PLL_CONFIG_VAL(20, 1, 0, 2),
255 MAKE_AR9331_CPU_PLL_CONFIG_VAL(32, 1, 0, 2),
257 MAKE_AR9331_SPI_CONTROL_VAL(6)
260 #if !defined(CONFIG_40MHZ_XTAL_SUPPORT)
263 MAKE_AR9331_CPU_CLK_CONTROL_VAL(1, 1, 2),
264 MAKE_AR9331_CPU_PLL_CONFIG_VAL(36, 1, 0, 2),
265 MAKE_AR9331_SPI_CONTROL_VAL(4)
270 MAKE_AR9331_CPU_CLK_CONTROL_VAL(1, 1, 1),
271 MAKE_AR9331_CPU_PLL_CONFIG_VAL(36, 1, 0, 2),
272 MAKE_AR9331_SPI_CONTROL_VAL(8)
278 MAKE_AR9331_CPU_CLK_CONTROL_VAL(1, 1, 2),
279 #if defined(CONFIG_40MHZ_XTAL_SUPPORT)
280 MAKE_AR9331_CPU_PLL_CONFIG_VAL(25, 1, 0, 2),
282 MAKE_AR9331_CPU_PLL_CONFIG_VAL(20, 1, 0, 1),
284 MAKE_AR9331_SPI_CONTROL_VAL(4)
289 MAKE_AR9331_CPU_CLK_CONTROL_VAL(1, 1, 1),
290 #if defined(CONFIG_40MHZ_XTAL_SUPPORT)
291 MAKE_AR9331_CPU_PLL_CONFIG_VAL(25, 1, 0, 2),
293 MAKE_AR9331_CPU_PLL_CONFIG_VAL(20, 1, 0, 1),
295 MAKE_AR9331_SPI_CONTROL_VAL(8)
300 MAKE_AR9331_CPU_CLK_CONTROL_VAL(1, 1, 2),
301 #if defined(CONFIG_40MHZ_XTAL_SUPPORT)
302 MAKE_AR9331_CPU_PLL_CONFIG_VAL(15, 1, 0, 1),
304 MAKE_AR9331_CPU_PLL_CONFIG_VAL(24, 1, 0, 1),
306 MAKE_AR9331_SPI_CONTROL_VAL(6)
309 #if !defined(CONFIG_40MHZ_XTAL_SUPPORT)
312 MAKE_AR9331_CPU_CLK_CONTROL_VAL(1, 1, 2),
313 MAKE_AR9331_CPU_PLL_CONFIG_VAL(26, 1, 0, 1),
314 MAKE_AR9331_SPI_CONTROL_VAL(6)
319 MAKE_AR9331_CPU_CLK_CONTROL_VAL(1, 1, 2),
320 MAKE_AR9331_CPU_PLL_CONFIG_VAL(28, 1, 0, 1),
321 MAKE_AR9331_SPI_CONTROL_VAL(6)
327 MAKE_AR9331_CPU_CLK_CONTROL_VAL(1, 1, 2),
328 #if defined(CONFIG_40MHZ_XTAL_SUPPORT)
329 MAKE_AR9331_CPU_PLL_CONFIG_VAL(18, 1, 0, 1),
331 MAKE_AR9331_CPU_PLL_CONFIG_VAL(29, 1, 0, 1),
333 MAKE_AR9331_SPI_CONTROL_VAL(6)
336 #if defined(CONFIG_40MHZ_XTAL_SUPPORT)
339 MAKE_AR9331_CPU_CLK_CONTROL_VAL(1, 1, 2),
340 MAKE_AR9331_CPU_PLL_CONFIG_VAL(19, 1, 0, 1),
341 MAKE_AR9331_SPI_CONTROL_VAL(6)
347 CPU_CLK_CONTROL_VAL_DEFAULT,
348 CPU_PLL_CONFIG_VAL_DEFAULT,
349 AR7240_SPI_CONTROL_DEFAULT
352 #if !defined(CONFIG_40MHZ_XTAL_SUPPORT)
355 MAKE_AR9331_CPU_CLK_CONTROL_VAL(1, 1, 2),
356 MAKE_AR9331_CPU_PLL_CONFIG_VAL(33, 1, 0, 1),
357 MAKE_AR9331_SPI_CONTROL_VAL(6)
361 #if defined(CONFIG_40MHZ_XTAL_SUPPORT)
364 MAKE_AR9331_CPU_CLK_CONTROL_VAL(1, 1, 2),
365 MAKE_AR9331_CPU_PLL_CONFIG_VAL(21, 1, 0, 1),
366 MAKE_AR9331_SPI_CONTROL_VAL(6)
370 #if !defined(CONFIG_40MHZ_XTAL_SUPPORT)
373 MAKE_AR9331_CPU_CLK_CONTROL_VAL(1, 1, 2),
374 MAKE_AR9331_CPU_PLL_CONFIG_VAL(34, 1, 0, 1),
375 MAKE_AR9331_SPI_CONTROL_VAL(6)
380 MAKE_AR9331_CPU_CLK_CONTROL_VAL(1, 1, 2),
381 MAKE_AR9331_CPU_PLL_CONFIG_VAL(35, 1, 0, 1),
382 MAKE_AR9331_SPI_CONTROL_VAL(8)
386 #if defined(CONFIG_40MHZ_XTAL_SUPPORT)
389 MAKE_AR9331_CPU_CLK_CONTROL_VAL(1, 1, 2),
390 MAKE_AR9331_CPU_PLL_CONFIG_VAL(22, 1, 0, 1),
391 MAKE_AR9331_SPI_CONTROL_VAL(8)
395 #if !defined(CONFIG_40MHZ_XTAL_SUPPORT)
398 MAKE_AR9331_CPU_CLK_CONTROL_VAL(1, 1, 2),
399 MAKE_AR9331_CPU_PLL_CONFIG_VAL(36, 1, 0, 1),
400 MAKE_AR9331_SPI_CONTROL_VAL(8)
406 MAKE_AR9331_CPU_CLK_CONTROL_VAL(1, 1, 2),
407 #if defined(CONFIG_40MHZ_XTAL_SUPPORT)
408 MAKE_AR9331_CPU_PLL_CONFIG_VAL(23, 1, 0, 1),
410 MAKE_AR9331_CPU_PLL_CONFIG_VAL(37, 1, 0, 1),
412 MAKE_AR9331_SPI_CONTROL_VAL(8)
415 #if !defined(CONFIG_40MHZ_XTAL_SUPPORT)
418 MAKE_AR9331_CPU_CLK_CONTROL_VAL(1, 1, 2),
419 MAKE_AR9331_CPU_PLL_CONFIG_VAL(38, 1, 0, 1),
420 MAKE_AR9331_SPI_CONTROL_VAL(8)
424 #if defined(CONFIG_40MHZ_XTAL_SUPPORT)
427 MAKE_AR9331_CPU_CLK_CONTROL_VAL(1, 1, 2),
428 MAKE_AR9331_CPU_PLL_CONFIG_VAL(24, 1, 0, 1),
429 MAKE_AR9331_SPI_CONTROL_VAL(8)
433 #if !defined(CONFIG_40MHZ_XTAL_SUPPORT)
436 MAKE_AR9331_CPU_CLK_CONTROL_VAL(1, 1, 2),
437 MAKE_AR9331_CPU_PLL_CONFIG_VAL(39, 1, 0, 1),
438 MAKE_AR9331_SPI_CONTROL_VAL(8)
444 MAKE_AR9331_CPU_CLK_CONTROL_VAL(1, 1, 2),
445 #if defined(CONFIG_40MHZ_XTAL_SUPPORT)
446 MAKE_AR9331_CPU_PLL_CONFIG_VAL(25, 1, 0, 1),
448 MAKE_AR9331_CPU_PLL_CONFIG_VAL(40, 1, 0, 1),
450 MAKE_AR9331_SPI_CONTROL_VAL(8)
455 MAKE_AR9331_CPU_CLK_CONTROL_VAL(1, 2, 2),
456 #if defined(CONFIG_40MHZ_XTAL_SUPPORT)
457 MAKE_AR9331_CPU_PLL_CONFIG_VAL(25, 1, 0, 1),
459 MAKE_AR9331_CPU_PLL_CONFIG_VAL(40, 1, 0, 1),
461 MAKE_AR9331_SPI_CONTROL_VAL(8)
464 #if defined(CONFIG_40MHZ_XTAL_SUPPORT)
467 MAKE_AR9331_CPU_CLK_CONTROL_VAL(1, 1, 2),
468 MAKE_AR9331_CPU_PLL_CONFIG_VAL(26, 1, 0, 1),
469 MAKE_AR9331_SPI_CONTROL_VAL(8)
473 #if !defined(CONFIG_40MHZ_XTAL_SUPPORT)
476 MAKE_AR9331_CPU_CLK_CONTROL_VAL(1, 2, 4),
477 MAKE_AR9331_CPU_PLL_CONFIG_VAL(42, 1, 0, 1),
478 MAKE_AR9331_SPI_CONTROL_VAL(4)
484 MAKE_AR9331_CPU_CLK_CONTROL_VAL(1, 2, 4),
485 #if defined(CONFIG_40MHZ_XTAL_SUPPORT)
486 MAKE_AR9331_CPU_PLL_CONFIG_VAL(28, 1, 0, 1),
488 MAKE_AR9331_CPU_PLL_CONFIG_VAL(45, 1, 0, 1),
490 MAKE_AR9331_SPI_CONTROL_VAL(4)
493 #if defined(CONFIG_40MHZ_XTAL_SUPPORT)
496 MAKE_AR9331_CPU_CLK_CONTROL_VAL(1, 2, 4),
497 MAKE_AR9331_CPU_PLL_CONFIG_VAL(29, 1, 0, 1),
498 MAKE_AR9331_SPI_CONTROL_VAL(4)
504 MAKE_AR9331_CPU_CLK_CONTROL_VAL(1, 2, 3),
505 #if CONFIG_40MHZ_XTAL_SUPPORT
506 MAKE_AR9331_CPU_PLL_CONFIG_VAL(30, 1, 0, 1),
508 MAKE_AR9331_CPU_PLL_CONFIG_VAL(48, 1, 0, 1),
510 MAKE_AR9331_SPI_CONTROL_VAL(6)
515 * Set and store PLL configuration in FLASH
517 int do_set_clocks(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]){
518 unsigned int cpu_pll_config_flash, cpu_clock_control_flash, spi_control_flash, reg;
519 unsigned int ahb_freq, ddr_freq, cpu_freq, spi_freq;
520 unsigned int *data_pointer;
521 int i, index, profiles_count;
524 profiles_count = sizeof(oc_profiles) / sizeof(ar9331_clock_profile);
526 // print all available profiles and current settings
530 ar7240_sys_frequency(&cpu_freq, &ddr_freq, &ahb_freq);
532 // calculate SPI clock (we need to set bit 0 to 1 in SPI_FUNC_SELECT to access SPI registers)
533 ar7240_reg_wr(AR7240_SPI_FS, 0x01);
534 spi_freq = ahb_freq / (((ar7240_reg_rd(AR7240_SPI_CLOCK) & 0x3F) + 1) * 2);
535 ar7240_reg_wr(AR7240_SPI_FS, 0x0);
543 printf("Current clocks (approximated):\n- CPU: %3d MHz\n", cpu_freq);
544 printf("- RAM: %3d MHz\n", ddr_freq);
545 printf("- AHB: %3d MHz\n", ahb_freq);
546 printf("- SPI: %3d MHz\n", spi_freq);
549 if(ar7240_reg_rd(HORNET_BOOTSTRAP_STATUS) & HORNET_BOOTSTRAP_SEL_25M_40M_MASK){
550 puts("- REF: 40 MHz\n\n");
552 puts("- REF: 25 MHz\n\n");
555 // do we have PLL_MAGIC in FLASH?
556 reg = ar7240_reg_rd(CFG_FLASH_BASE + PLL_IN_FLASH_DATA_BLOCK_OFFSET + PLL_IN_FLASH_MAGIC_OFFSET);
558 // read all register values stored in FLASH
559 cpu_pll_config_flash = ar7240_reg_rd(CFG_FLASH_BASE + PLL_IN_FLASH_DATA_BLOCK_OFFSET + PLL_IN_FLASH_MAGIC_OFFSET + 4);
560 cpu_clock_control_flash = ar7240_reg_rd(CFG_FLASH_BASE + PLL_IN_FLASH_DATA_BLOCK_OFFSET + PLL_IN_FLASH_MAGIC_OFFSET + 8);
561 spi_control_flash = ar7240_reg_rd(CFG_FLASH_BASE + PLL_IN_FLASH_DATA_BLOCK_OFFSET + PLL_IN_FLASH_MAGIC_OFFSET + 12);
563 printf("Available PLL and clocks configurations: %d\n\n", profiles_count);
565 puts(" | CPU | RAM | AHB | SPI | [ ]\n ---------------------------------\n");
567 for(i = 0; i < profiles_count; i++){
568 printf("%4d. |%4d |%4d |%4d |%4d | ", i + 1,
569 oc_profiles[i].cpu_clock,
570 oc_profiles[i].ram_clock,
571 oc_profiles[i].ahb_clock,
572 oc_profiles[i].spi_clock);
574 if(reg == PLL_IN_FLASH_MAGIC &&
575 oc_profiles[i].cpu_pll_config == cpu_pll_config_flash &&
576 oc_profiles[i].cpu_clk_control == cpu_clock_control_flash &&
577 oc_profiles[i].spi_control == spi_control_flash){
584 puts("\n[*] = currently selected profile (stored in FLASH).\nAll clocks in MHz, run 'setclocks X' to choose one.\n\n");
585 puts("** Notice:\n you should always make a backup of your device\n entire FLASH content before making any changes\n\n");
590 index = simple_strtoul(argv[1], NULL, 10);
592 if(index > profiles_count || index < 1){
593 printf("## Error: selected index should be in range 1..%d!\n", profiles_count);
597 printf("You have selected profile: %d.\n\n", index);
599 // array is zero-based indexing
602 // backup entire block in which we store PLL/CLK settings
603 data_pointer = (unsigned int *)WEBFAILSAFE_UPLOAD_RAM_ADDRESS;
606 puts("## Error: couldn't allocate RAM for data block backup!\n");
610 memcpy((void *)data_pointer, (void *)(CFG_FLASH_BASE + PLL_IN_FLASH_DATA_BLOCK_OFFSET), PLL_IN_FLASH_DATA_BLOCK_LENGTH);
612 // save PLL_IN_FLASH_MAGIC and PLL/clocks registers values
613 data_pointer = (unsigned int *)(WEBFAILSAFE_UPLOAD_RAM_ADDRESS + PLL_IN_FLASH_MAGIC_OFFSET);
614 *data_pointer = PLL_IN_FLASH_MAGIC;
617 *data_pointer = oc_profiles[index].cpu_pll_config;
620 *data_pointer = oc_profiles[index].cpu_clk_control;
623 *data_pointer = oc_profiles[index].spi_control;
625 // erase FLASH, copy data from RAM
627 "erase 0x%lX +0x%lX; cp.b 0x%lX 0x%lX 0x%lX",
628 CFG_FLASH_BASE + PLL_IN_FLASH_DATA_BLOCK_OFFSET,
629 PLL_IN_FLASH_DATA_BLOCK_LENGTH,
630 WEBFAILSAFE_UPLOAD_RAM_ADDRESS,
631 CFG_FLASH_BASE + PLL_IN_FLASH_DATA_BLOCK_OFFSET,
632 PLL_IN_FLASH_DATA_BLOCK_LENGTH);
634 printf("Executing: %s\n\n", buf);
636 return(run_command(buf, 0));
640 U_BOOT_CMD(setclocks, 2, 0, do_set_clocks, "select clocks configuration from predefined list\n",
642 "\t- save 'index' configuration in FLASH\n"
644 "\t- prints available clocks configurations and current settings");
647 * Remove (clear) PLL and clock settings in FLASH
649 int do_clear_clocks(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]){
650 unsigned char *data_pointer;
653 unsigned int reg = 0;
655 // do we have PLL_MAGIC in FLASH?
656 reg = ar7240_reg_rd(CFG_FLASH_BASE + PLL_IN_FLASH_DATA_BLOCK_OFFSET + PLL_IN_FLASH_MAGIC_OFFSET);
658 if(reg == PLL_IN_FLASH_MAGIC){
659 // backup entire block in which we store PLL/CLK settings
660 data_pointer = (unsigned char *)WEBFAILSAFE_UPLOAD_RAM_ADDRESS;
663 puts("## Error: couldn't allocate RAM for data block backup!\n");
667 memcpy((void *)data_pointer, (void *)(CFG_FLASH_BASE + PLL_IN_FLASH_DATA_BLOCK_OFFSET), PLL_IN_FLASH_DATA_BLOCK_LENGTH);
669 // 16 bytes (4x 32-bit values)
670 for(i = 0; i < 16; i++){
671 data_pointer[PLL_IN_FLASH_MAGIC_OFFSET + i] = 0xFF;
674 // erase FLASH, copy data from RAM
676 "erase 0x%lX +0x%lX; cp.b 0x%lX 0x%lX 0x%lX",
677 CFG_FLASH_BASE + PLL_IN_FLASH_DATA_BLOCK_OFFSET,
678 PLL_IN_FLASH_DATA_BLOCK_LENGTH,
679 WEBFAILSAFE_UPLOAD_RAM_ADDRESS,
680 CFG_FLASH_BASE + PLL_IN_FLASH_DATA_BLOCK_OFFSET,
681 PLL_IN_FLASH_DATA_BLOCK_LENGTH);
683 printf("Executing: %s\n\n", buf);
685 return(run_command(buf, 0));
687 puts("** Warning: there is no PLL and clocks configuration in FLASH!\n");
692 U_BOOT_CMD(clearclocks, 1, 0, do_clear_clocks, "remove PLL and clocks configuration from FLASH\n", NULL);
693 #endif /* #if defined(PLL_IN_FLASH_MAGIC_OFFSET) */