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 /* TODO: remove extern and include header file*/
30 extern void qca_sys_clocks(u32 *cpu_clk, u32 *ddr_clk, u32 *ahb_clk,
31 u32 *spi_clk, u32 *ref_clk);
33 #if defined(OFFSET_MAC_ADDRESS)
35 * Show MAC address(es)
37 int do_print_mac(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]){
39 #if defined(OFFSET_MAC_ADDRESS2)
43 #if defined(OFFSET_MAC_ADDRESS2)
44 // get MAC1 and MAC2 addresses from flash and print them
45 memcpy(buffer, (void *)(CFG_FLASH_BASE + OFFSET_MAC_DATA_BLOCK + OFFSET_MAC_ADDRESS), 6);
46 memcpy(buffer2, (void *)(CFG_FLASH_BASE + OFFSET_MAC_DATA_BLOCK + OFFSET_MAC_ADDRESS2), 6);
48 puts("Current MAC addresses stored in FLASH:\n");
49 printf("MAC1 at 0x%X: %02X:%02X:%02X:%02X:%02X:%02X\n", CFG_FLASH_BASE + OFFSET_MAC_DATA_BLOCK + OFFSET_MAC_ADDRESS,
50 buffer[0] & 0xFF, buffer[1] & 0xFF, buffer[2] & 0xFF, buffer[3] & 0xFF, buffer[4] & 0xFF, buffer[5] & 0xFF);
52 printf("MAC2 at 0x%X: %02X:%02X:%02X:%02X:%02X:%02X\n\n", CFG_FLASH_BASE + OFFSET_MAC_DATA_BLOCK + OFFSET_MAC_ADDRESS2,
53 buffer2[0] & 0xFF, buffer2[1] & 0xFF, buffer2[2] & 0xFF, buffer2[3] & 0xFF, buffer2[4] & 0xFF, buffer2[5] & 0xFF);
55 // get MAC address from flash and print it
56 memcpy(buffer, (void *)(CFG_FLASH_BASE + OFFSET_MAC_DATA_BLOCK + OFFSET_MAC_ADDRESS), 6);
58 printf("Current MAC address stored in FLASH at offset 0x%X: ", CFG_FLASH_BASE + OFFSET_MAC_DATA_BLOCK + OFFSET_MAC_ADDRESS);
59 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);
65 #if defined(OFFSET_MAC_ADDRESS2)
66 U_BOOT_CMD(printmac, 1, 1, do_print_mac, "print MAC addresses stored in FLASH\n", NULL);
68 U_BOOT_CMD(printmac, 1, 1, do_print_mac, "print MAC address stored in FLASH\n", NULL);
72 * Change MAC address(es)
74 int do_set_mac(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]){
75 unsigned char *data_pointer;
79 // allow only 2 arg (command name + mac), second argument length should be 17 (xx:xx:xx:xx:xx:xx)
80 if(argc != 2 || strlen(argv[1]) != 17){
81 #if defined(CFG_LONGHELP)
82 if(cmdtp->help != NULL){
83 printf("Usage:\n%s %s\n", cmdtp->name, cmdtp->help);
85 printf("Usage:\n%s %s\n", cmdtp->name, cmdtp->usage);
88 printf("Usage:\n%s %s\n", cmdtp->name, cmdtp->usage);
94 for(i = 0; i< 17; i++){
95 if(argv[1][i] == ':'){
101 puts("## Error: given MAC address has wrong format (should be: xx:xx:xx:xx:xx:xx)!\n");
105 // backup block with MAC address from flash in RAM
106 data_pointer = (unsigned char *)WEBFAILSAFE_UPLOAD_RAM_ADDRESS;
109 puts("## Error: couldn't allocate RAM for data block backup!\n");
113 puts("** Notice:\n you should always make a backup of your device\n entire FLASH content before making any changes\n\n");
115 memcpy((void *)data_pointer, (void *)(CFG_FLASH_BASE + OFFSET_MAC_DATA_BLOCK), OFFSET_MAC_DATA_BLOCK_LENGTH);
117 // store new MAC address in RAM
118 for(i = 0; i < 6; i++){
119 data_pointer[OFFSET_MAC_ADDRESS + i] = simple_strtoul((char *)(argv[1] + i*3), NULL, 16);
122 // now we can erase flash and write data from RAM
124 "erase 0x%lX +0x%lX; cp.b 0x%lX 0x%lX 0x%lX",
125 CFG_FLASH_BASE + OFFSET_MAC_DATA_BLOCK,
126 OFFSET_MAC_DATA_BLOCK_LENGTH,
127 WEBFAILSAFE_UPLOAD_RAM_ADDRESS,
128 CFG_FLASH_BASE + OFFSET_MAC_DATA_BLOCK,
129 OFFSET_MAC_DATA_BLOCK_LENGTH);
131 printf("Executing: %s\n\n", buf);
133 return(run_command(buf, 0));
136 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");
138 #endif /* if defined(OFFSET_MAC_ADDRESS) */
140 #if defined(OFFSET_ROUTER_MODEL)
142 * Show TP-Link router model
144 int do_print_model(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]){
145 unsigned char buffer[8];
147 // get router model from flash and print it
148 memcpy(buffer, (void *)(CFG_FLASH_BASE + OFFSET_MAC_DATA_BLOCK + OFFSET_ROUTER_MODEL), 8);
150 printf("Router model stored in FLASH at offset 0x%X: ", CFG_FLASH_BASE + OFFSET_MAC_DATA_BLOCK + OFFSET_ROUTER_MODEL);
151 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);
156 U_BOOT_CMD(printmodel, 1, 1, do_print_model, "print router model stored in FLASH\n", NULL);
158 #endif /* if defined(OFFSET_ROUTER_MODEL) */
160 #if defined(OFFSET_PIN_NUMBER)
164 int do_print_pin(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]){
165 unsigned char buffer[9];
167 // get pin number from flash and print it
168 memcpy(buffer, (void *)(CFG_FLASH_BASE + OFFSET_MAC_DATA_BLOCK + OFFSET_PIN_NUMBER), 8);
171 printf("Router pin number stored in FLASH at offset 0x%X: ", CFG_FLASH_BASE + OFFSET_MAC_DATA_BLOCK + OFFSET_PIN_NUMBER);
172 printf("%s\n\n", buffer);
177 U_BOOT_CMD(printpin, 1, 1, do_print_pin, "print WPS pin stored in FLASH\n", NULL);
179 #endif /* if defined(OFFSET_PIN_NUMBER) */
181 #if defined(CONFIG_NETCONSOLE)
185 int do_start_nc(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]){
186 return(run_command("setenv stdin nc;setenv stdout nc;setenv stderr nc;version;", 0));
189 U_BOOT_CMD(startnc, 1, 0, do_start_nc, "start net console\n", NULL);
192 * Start Serial Console
194 int do_start_sc(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]){
195 return(run_command("setenv stdin serial;setenv stdout serial;setenv stderr serial;version;", 0));
198 U_BOOT_CMD(startsc, 1, 0, do_start_sc, "start serial console\n", NULL);
200 #endif /* if defined(CONFIG_NETCONSOLE) */
202 #if !defined(CONFIG_FOR_DLINK_DIR505_A1)
204 * Erase environment sector
206 int do_default_env(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]){
209 ulong end_addr, flash_sect_addr;
210 #if defined(CFG_ENV_SECT_SIZE) && (CFG_ENV_SECT_SIZE > CFG_ENV_SIZE)
212 unsigned char env_buffer[CFG_ENV_SECT_SIZE];
215 #if defined(CFG_ENV_SECT_SIZE) && (CFG_ENV_SECT_SIZE > CFG_ENV_SIZE)
216 flash_offset = CFG_ENV_ADDR & (CFG_ENV_SECT_SIZE-1);
217 flash_sect_addr = CFG_ENV_ADDR & ~(CFG_ENV_SECT_SIZE-1);
219 /* copy whole env sector to temporary buffer */
220 memcpy(env_buffer, (void *)flash_sect_addr, CFG_ENV_SECT_SIZE);
223 memset((uchar *)((unsigned long)env_buffer + flash_offset), 0xFF, CFG_ENV_SIZE);
225 len = CFG_ENV_SECT_SIZE;
227 flash_sect_addr = CFG_ENV_ADDR;
231 end_addr = flash_sect_addr + len - 1;
233 /* erase whole env sector */
234 if(flash_sect_erase(flash_sect_addr, end_addr)){
238 #if defined(CFG_ENV_SECT_SIZE) && (CFG_ENV_SECT_SIZE > CFG_ENV_SIZE)
239 /* restore data from buffer in FLASH */
240 rc = flash_write((char *)env_buffer, flash_sect_addr, len);
251 U_BOOT_CMD(defenv, 1, 0, do_default_env, "reset environment variables to their default values\n", NULL);
252 #endif /* if !defined(CONFIG_FOR_DLINK_DIR505_A1) */
254 #if defined(PLL_IN_FLASH_MAGIC_OFFSET)
258 unsigned short cpu_clock;
259 unsigned short ram_clock;
260 unsigned short ahb_clock;
261 unsigned short spi_clock;
264 // (more info in includes/configs/ap121.h)
265 unsigned int cpu_clk_control;
266 unsigned int cpu_pll_config;
267 unsigned int spi_control;
268 } ar9331_clock_profile;
270 static const ar9331_clock_profile oc_profiles[] = {
273 MAKE_AR9331_CPU_CLK_CONTROL_VAL(1, 1, 2),
274 #if defined(CONFIG_40MHZ_XTAL_SUPPORT)
275 MAKE_AR9331_CPU_PLL_CONFIG_VAL(20, 1, 0, 2),
277 MAKE_AR9331_CPU_PLL_CONFIG_VAL(32, 1, 0, 2),
279 MAKE_AR9331_SPI_CONTROL_VAL(4)
284 MAKE_AR9331_CPU_CLK_CONTROL_VAL(1, 1, 1),
285 #if defined(CONFIG_40MHZ_XTAL_SUPPORT)
286 MAKE_AR9331_CPU_PLL_CONFIG_VAL(20, 1, 0, 2),
288 MAKE_AR9331_CPU_PLL_CONFIG_VAL(32, 1, 0, 2),
290 MAKE_AR9331_SPI_CONTROL_VAL(6)
293 #if !defined(CONFIG_40MHZ_XTAL_SUPPORT)
296 MAKE_AR9331_CPU_CLK_CONTROL_VAL(1, 1, 2),
297 MAKE_AR9331_CPU_PLL_CONFIG_VAL(36, 1, 0, 2),
298 MAKE_AR9331_SPI_CONTROL_VAL(4)
303 MAKE_AR9331_CPU_CLK_CONTROL_VAL(1, 1, 1),
304 MAKE_AR9331_CPU_PLL_CONFIG_VAL(36, 1, 0, 2),
305 MAKE_AR9331_SPI_CONTROL_VAL(8)
311 MAKE_AR9331_CPU_CLK_CONTROL_VAL(1, 1, 2),
312 #if defined(CONFIG_40MHZ_XTAL_SUPPORT)
313 MAKE_AR9331_CPU_PLL_CONFIG_VAL(25, 1, 0, 2),
315 MAKE_AR9331_CPU_PLL_CONFIG_VAL(20, 1, 0, 1),
317 MAKE_AR9331_SPI_CONTROL_VAL(4)
322 MAKE_AR9331_CPU_CLK_CONTROL_VAL(1, 1, 1),
323 #if defined(CONFIG_40MHZ_XTAL_SUPPORT)
324 MAKE_AR9331_CPU_PLL_CONFIG_VAL(25, 1, 0, 2),
326 MAKE_AR9331_CPU_PLL_CONFIG_VAL(20, 1, 0, 1),
328 MAKE_AR9331_SPI_CONTROL_VAL(8)
333 MAKE_AR9331_CPU_CLK_CONTROL_VAL(1, 1, 2),
334 #if defined(CONFIG_40MHZ_XTAL_SUPPORT)
335 MAKE_AR9331_CPU_PLL_CONFIG_VAL(15, 1, 0, 1),
337 MAKE_AR9331_CPU_PLL_CONFIG_VAL(24, 1, 0, 1),
339 MAKE_AR9331_SPI_CONTROL_VAL(6)
342 #if !defined(CONFIG_40MHZ_XTAL_SUPPORT)
345 MAKE_AR9331_CPU_CLK_CONTROL_VAL(1, 1, 2),
346 MAKE_AR9331_CPU_PLL_CONFIG_VAL(26, 1, 0, 1),
347 MAKE_AR9331_SPI_CONTROL_VAL(6)
352 MAKE_AR9331_CPU_CLK_CONTROL_VAL(1, 1, 2),
353 MAKE_AR9331_CPU_PLL_CONFIG_VAL(28, 1, 0, 1),
354 MAKE_AR9331_SPI_CONTROL_VAL(6)
360 MAKE_AR9331_CPU_CLK_CONTROL_VAL(1, 1, 2),
361 #if defined(CONFIG_40MHZ_XTAL_SUPPORT)
362 MAKE_AR9331_CPU_PLL_CONFIG_VAL(18, 1, 0, 1),
364 MAKE_AR9331_CPU_PLL_CONFIG_VAL(29, 1, 0, 1),
366 MAKE_AR9331_SPI_CONTROL_VAL(6)
369 #if defined(CONFIG_40MHZ_XTAL_SUPPORT)
372 MAKE_AR9331_CPU_CLK_CONTROL_VAL(1, 1, 2),
373 MAKE_AR9331_CPU_PLL_CONFIG_VAL(19, 1, 0, 1),
374 MAKE_AR9331_SPI_CONTROL_VAL(6)
380 CPU_CLK_CONTROL_VAL_DEFAULT,
381 CPU_PLL_CONFIG_VAL_DEFAULT,
382 AR7240_SPI_CONTROL_DEFAULT
385 #if !defined(CONFIG_40MHZ_XTAL_SUPPORT)
388 MAKE_AR9331_CPU_CLK_CONTROL_VAL(1, 1, 2),
389 MAKE_AR9331_CPU_PLL_CONFIG_VAL(33, 1, 0, 1),
390 MAKE_AR9331_SPI_CONTROL_VAL(6)
394 #if defined(CONFIG_40MHZ_XTAL_SUPPORT)
397 MAKE_AR9331_CPU_CLK_CONTROL_VAL(1, 1, 2),
398 MAKE_AR9331_CPU_PLL_CONFIG_VAL(21, 1, 0, 1),
399 MAKE_AR9331_SPI_CONTROL_VAL(6)
403 #if !defined(CONFIG_40MHZ_XTAL_SUPPORT)
406 MAKE_AR9331_CPU_CLK_CONTROL_VAL(1, 1, 2),
407 MAKE_AR9331_CPU_PLL_CONFIG_VAL(34, 1, 0, 1),
408 MAKE_AR9331_SPI_CONTROL_VAL(6)
413 MAKE_AR9331_CPU_CLK_CONTROL_VAL(1, 1, 2),
414 MAKE_AR9331_CPU_PLL_CONFIG_VAL(35, 1, 0, 1),
415 MAKE_AR9331_SPI_CONTROL_VAL(8)
419 #if defined(CONFIG_40MHZ_XTAL_SUPPORT)
422 MAKE_AR9331_CPU_CLK_CONTROL_VAL(1, 1, 2),
423 MAKE_AR9331_CPU_PLL_CONFIG_VAL(22, 1, 0, 1),
424 MAKE_AR9331_SPI_CONTROL_VAL(8)
428 #if !defined(CONFIG_40MHZ_XTAL_SUPPORT)
431 MAKE_AR9331_CPU_CLK_CONTROL_VAL(1, 1, 2),
432 MAKE_AR9331_CPU_PLL_CONFIG_VAL(36, 1, 0, 1),
433 MAKE_AR9331_SPI_CONTROL_VAL(8)
439 MAKE_AR9331_CPU_CLK_CONTROL_VAL(1, 1, 2),
440 #if defined(CONFIG_40MHZ_XTAL_SUPPORT)
441 MAKE_AR9331_CPU_PLL_CONFIG_VAL(23, 1, 0, 1),
443 MAKE_AR9331_CPU_PLL_CONFIG_VAL(37, 1, 0, 1),
445 MAKE_AR9331_SPI_CONTROL_VAL(8)
448 #if !defined(CONFIG_40MHZ_XTAL_SUPPORT)
451 MAKE_AR9331_CPU_CLK_CONTROL_VAL(1, 1, 2),
452 MAKE_AR9331_CPU_PLL_CONFIG_VAL(38, 1, 0, 1),
453 MAKE_AR9331_SPI_CONTROL_VAL(8)
457 #if defined(CONFIG_40MHZ_XTAL_SUPPORT)
460 MAKE_AR9331_CPU_CLK_CONTROL_VAL(1, 1, 2),
461 MAKE_AR9331_CPU_PLL_CONFIG_VAL(24, 1, 0, 1),
462 MAKE_AR9331_SPI_CONTROL_VAL(8)
466 #if !defined(CONFIG_40MHZ_XTAL_SUPPORT)
469 MAKE_AR9331_CPU_CLK_CONTROL_VAL(1, 1, 2),
470 MAKE_AR9331_CPU_PLL_CONFIG_VAL(39, 1, 0, 1),
471 MAKE_AR9331_SPI_CONTROL_VAL(8)
477 MAKE_AR9331_CPU_CLK_CONTROL_VAL(1, 1, 2),
478 #if defined(CONFIG_40MHZ_XTAL_SUPPORT)
479 MAKE_AR9331_CPU_PLL_CONFIG_VAL(25, 1, 0, 1),
481 MAKE_AR9331_CPU_PLL_CONFIG_VAL(40, 1, 0, 1),
483 MAKE_AR9331_SPI_CONTROL_VAL(8)
488 MAKE_AR9331_CPU_CLK_CONTROL_VAL(1, 2, 2),
489 #if defined(CONFIG_40MHZ_XTAL_SUPPORT)
490 MAKE_AR9331_CPU_PLL_CONFIG_VAL(25, 1, 0, 1),
492 MAKE_AR9331_CPU_PLL_CONFIG_VAL(40, 1, 0, 1),
494 MAKE_AR9331_SPI_CONTROL_VAL(8)
497 #if defined(CONFIG_40MHZ_XTAL_SUPPORT)
500 MAKE_AR9331_CPU_CLK_CONTROL_VAL(1, 1, 2),
501 MAKE_AR9331_CPU_PLL_CONFIG_VAL(26, 1, 0, 1),
502 MAKE_AR9331_SPI_CONTROL_VAL(8)
506 #if !defined(CONFIG_40MHZ_XTAL_SUPPORT)
509 MAKE_AR9331_CPU_CLK_CONTROL_VAL(1, 2, 4),
510 MAKE_AR9331_CPU_PLL_CONFIG_VAL(42, 1, 0, 1),
511 MAKE_AR9331_SPI_CONTROL_VAL(4)
517 MAKE_AR9331_CPU_CLK_CONTROL_VAL(1, 2, 4),
518 #if defined(CONFIG_40MHZ_XTAL_SUPPORT)
519 MAKE_AR9331_CPU_PLL_CONFIG_VAL(28, 1, 0, 1),
521 MAKE_AR9331_CPU_PLL_CONFIG_VAL(45, 1, 0, 1),
523 MAKE_AR9331_SPI_CONTROL_VAL(4)
526 #if defined(CONFIG_40MHZ_XTAL_SUPPORT)
529 MAKE_AR9331_CPU_CLK_CONTROL_VAL(1, 2, 4),
530 MAKE_AR9331_CPU_PLL_CONFIG_VAL(29, 1, 0, 1),
531 MAKE_AR9331_SPI_CONTROL_VAL(4)
537 MAKE_AR9331_CPU_CLK_CONTROL_VAL(1, 2, 3),
538 #if CONFIG_40MHZ_XTAL_SUPPORT
539 MAKE_AR9331_CPU_PLL_CONFIG_VAL(30, 1, 0, 1),
541 MAKE_AR9331_CPU_PLL_CONFIG_VAL(48, 1, 0, 1),
543 MAKE_AR9331_SPI_CONTROL_VAL(6)
548 * Set and store PLL configuration in FLASH
550 int do_set_clocks(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]){
551 unsigned int cpu_pll_config_flash, cpu_clock_control_flash, spi_control_flash, reg;
552 unsigned int ahb_freq, ddr_freq, cpu_freq, spi_freq;
553 unsigned int *data_pointer;
554 int i, index, profiles_count;
557 profiles_count = sizeof(oc_profiles) / sizeof(ar9331_clock_profile);
559 // print all available profiles and current settings
563 qca_sys_clocks(&cpu_freq, &ddr_freq, &ahb_freq, NULL, NULL);
565 // calculate SPI clock (we need to set bit 0 to 1 in SPI_FUNC_SELECT to access SPI registers)
566 ar7240_reg_wr(AR7240_SPI_FS, 0x01);
567 spi_freq = ahb_freq / (((ar7240_reg_rd(AR7240_SPI_CLOCK) & 0x3F) + 1) * 2);
568 ar7240_reg_wr(AR7240_SPI_FS, 0x0);
576 printf("Current clocks (approximated):\n- CPU: %3d MHz\n", cpu_freq);
577 printf("- RAM: %3d MHz\n", ddr_freq);
578 printf("- AHB: %3d MHz\n", ahb_freq);
579 printf("- SPI: %3d MHz\n", spi_freq);
582 if(ar7240_reg_rd(HORNET_BOOTSTRAP_STATUS) & HORNET_BOOTSTRAP_SEL_25M_40M_MASK){
583 puts("- REF: 40 MHz\n\n");
585 puts("- REF: 25 MHz\n\n");
588 // do we have PLL_MAGIC in FLASH?
589 reg = ar7240_reg_rd(CFG_FLASH_BASE + PLL_IN_FLASH_DATA_BLOCK_OFFSET + PLL_IN_FLASH_MAGIC_OFFSET);
591 // read all register values stored in FLASH
592 cpu_pll_config_flash = ar7240_reg_rd(CFG_FLASH_BASE + PLL_IN_FLASH_DATA_BLOCK_OFFSET + PLL_IN_FLASH_MAGIC_OFFSET + 4);
593 cpu_clock_control_flash = ar7240_reg_rd(CFG_FLASH_BASE + PLL_IN_FLASH_DATA_BLOCK_OFFSET + PLL_IN_FLASH_MAGIC_OFFSET + 8);
594 spi_control_flash = ar7240_reg_rd(CFG_FLASH_BASE + PLL_IN_FLASH_DATA_BLOCK_OFFSET + PLL_IN_FLASH_MAGIC_OFFSET + 12);
596 printf("Available PLL and clocks configurations: %d\n\n", profiles_count);
598 puts(" | CPU | RAM | AHB | SPI | [ ]\n ---------------------------------\n");
600 for(i = 0; i < profiles_count; i++){
601 printf("%4d. |%4d |%4d |%4d |%4d | ", i + 1,
602 oc_profiles[i].cpu_clock,
603 oc_profiles[i].ram_clock,
604 oc_profiles[i].ahb_clock,
605 oc_profiles[i].spi_clock);
607 if(reg == PLL_IN_FLASH_MAGIC &&
608 oc_profiles[i].cpu_pll_config == cpu_pll_config_flash &&
609 oc_profiles[i].cpu_clk_control == cpu_clock_control_flash &&
610 oc_profiles[i].spi_control == spi_control_flash){
617 puts("\n[*] = currently selected profile (stored in FLASH).\nAll clocks in MHz, run 'setclk X' to choose one.\n\n");
618 puts("** Notice:\n you should always make a backup of your device\n entire FLASH content before making any changes\n\n");
623 index = simple_strtoul(argv[1], NULL, 10);
625 if(index > profiles_count || index < 1){
626 printf("## Error: selected index should be in range 1..%d!\n", profiles_count);
630 printf("You have selected profile: %d.\n\n", index);
632 // array is zero-based indexing
635 // backup entire block in which we store PLL/CLK settings
636 data_pointer = (unsigned int *)WEBFAILSAFE_UPLOAD_RAM_ADDRESS;
639 puts("## Error: couldn't allocate RAM for data block backup!\n");
643 memcpy((void *)data_pointer, (void *)(CFG_FLASH_BASE + PLL_IN_FLASH_DATA_BLOCK_OFFSET), PLL_IN_FLASH_DATA_BLOCK_LENGTH);
645 // save PLL_IN_FLASH_MAGIC and PLL/clocks registers values
646 data_pointer = (unsigned int *)(WEBFAILSAFE_UPLOAD_RAM_ADDRESS + PLL_IN_FLASH_MAGIC_OFFSET);
647 *data_pointer = PLL_IN_FLASH_MAGIC;
650 *data_pointer = oc_profiles[index].cpu_pll_config;
653 *data_pointer = oc_profiles[index].cpu_clk_control;
656 *data_pointer = oc_profiles[index].spi_control;
658 // erase FLASH, copy data from RAM
660 "erase 0x%lX +0x%lX; cp.b 0x%lX 0x%lX 0x%lX",
661 CFG_FLASH_BASE + PLL_IN_FLASH_DATA_BLOCK_OFFSET,
662 PLL_IN_FLASH_DATA_BLOCK_LENGTH,
663 WEBFAILSAFE_UPLOAD_RAM_ADDRESS,
664 CFG_FLASH_BASE + PLL_IN_FLASH_DATA_BLOCK_OFFSET,
665 PLL_IN_FLASH_DATA_BLOCK_LENGTH);
667 printf("Executing: %s\n\n", buf);
669 return(run_command(buf, 0));
673 U_BOOT_CMD(setclk, 2, 0, do_set_clocks, "select clocks configuration from predefined list\n",
675 "\t- save 'index' configuration in FLASH\n"
677 "\t- prints available clocks configurations and current settings\n");
680 * Remove (clear) PLL and clock settings in FLASH
682 int do_clear_clocks(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]){
683 unsigned char *data_pointer;
686 unsigned int reg = 0;
688 // do we have PLL_MAGIC in FLASH?
689 reg = ar7240_reg_rd(CFG_FLASH_BASE + PLL_IN_FLASH_DATA_BLOCK_OFFSET + PLL_IN_FLASH_MAGIC_OFFSET);
691 if(reg == PLL_IN_FLASH_MAGIC){
692 // backup entire block in which we store PLL/CLK settings
693 data_pointer = (unsigned char *)WEBFAILSAFE_UPLOAD_RAM_ADDRESS;
696 puts("## Error: couldn't allocate RAM for data block backup!\n");
700 memcpy((void *)data_pointer, (void *)(CFG_FLASH_BASE + PLL_IN_FLASH_DATA_BLOCK_OFFSET), PLL_IN_FLASH_DATA_BLOCK_LENGTH);
702 // 16 bytes (4x 32-bit values)
703 for(i = 0; i < 16; i++){
704 data_pointer[PLL_IN_FLASH_MAGIC_OFFSET + i] = 0xFF;
707 // erase FLASH, copy data from RAM
709 "erase 0x%lX +0x%lX; cp.b 0x%lX 0x%lX 0x%lX",
710 CFG_FLASH_BASE + PLL_IN_FLASH_DATA_BLOCK_OFFSET,
711 PLL_IN_FLASH_DATA_BLOCK_LENGTH,
712 WEBFAILSAFE_UPLOAD_RAM_ADDRESS,
713 CFG_FLASH_BASE + PLL_IN_FLASH_DATA_BLOCK_OFFSET,
714 PLL_IN_FLASH_DATA_BLOCK_LENGTH);
716 printf("Executing: %s\n\n", buf);
718 return(run_command(buf, 0));
720 puts("** Warning: there is no PLL and clocks configuration in FLASH!\n");
725 U_BOOT_CMD(clearclk, 1, 0, do_clear_clocks, "remove PLL and clocks configuration from FLASH\n", NULL);
726 #endif /* #if defined(PLL_IN_FLASH_MAGIC_OFFSET) */