PLL/clocks settings in FLASH and O/C recovery for AR9331, other minor changes, AR9344...
authorPiotr Dymacz <pepe2k@gmail.com>
Wed, 4 Dec 2013 22:08:07 +0000 (23:08 +0100)
committerPiotr Dymacz <pepe2k@gmail.com>
Wed, 4 Dec 2013 22:08:07 +0000 (23:08 +0100)
28 files changed:
u-boot/Makefile
u-boot/board/ar7240/ap121/ap121.c
u-boot/board/ar7240/ap121/hornet_pll_init.S
u-boot/board/ar7240/common/ar7240_flash.c
u-boot/board/ar7240/common/ar7240_s26_phy.c
u-boot/board/ar7240/common/lowlevel_init_934x.S
u-boot/board/ar7240/db12x/db12x.c
u-boot/common/cmd_custom.c
u-boot/common/env_common.c
u-boot/cpu/mips/ar7240/ag7240.c
u-boot/cpu/mips/ar7240/ag934x.c
u-boot/cpu/mips/ar7240/ar7240_serial.c
u-boot/cpu/mips/ar7240/hornet_serial.c
u-boot/cpu/mips/start.S
u-boot/cpu/mips/start_bootstrap.S
u-boot/include/ar7240_soc.h
u-boot/include/asm-mips/u-boot.h
u-boot/include/configs/ap121.h
u-boot/include/configs/ar7240.h
u-boot/include/configs/db12x.h
u-boot/lib_bootstrap/time.c
u-boot/lib_mips/board.c
u-boot/lib_mips/time.c
u-boot/net/bootp.c
u-boot/net/net.c
u-boot/net/rarp.c
u-boot/net/sntp.c
u-boot/net/tftp.c

index ec5309e1206e4bf9e6c98b37bce85670aec3617d..3f19d9a97ccc52a9c811d11c05962844c3bcd205 100755 (executable)
@@ -279,6 +279,10 @@ ifdef CONFIG_BOOTDELAY
        @echo "#define CONFIG_BOOTDELAY "$(CONFIG_BOOTDELAY)   >> include/config.h
 endif
 
+ifdef CFG_PLL_FREQ
+       @echo "#define CFG_PLL_FREQ "$(CFG_PLL_FREQ)           >> include/config.h
+endif
+
        @echo "#define CONFIG_DELAY_TO_AUTORUN_HTTPD        3" >> include/config.h
        @echo "#define CONFIG_DELAY_TO_AUTORUN_CONSOLE      5" >> include/config.h
        @echo "#define CONFIG_DELAY_TO_AUTORUN_NETCONSOLE   7" >> include/config.h
index 7efdc263e851a8ba21309852c6c7252dcc50b7b7..02eccb4ed80b6a420832ddade9142b6bc2031d88 100755 (executable)
@@ -129,7 +129,11 @@ void all_led_off(void){
        #error "GPIO_RST_BUTTON_BIT not defined!"
 #endif
 int reset_button_status(void){
-       if(ar7240_reg_rd(AR7240_GPIO_IN) & (1 << GPIO_RST_BUTTON_BIT)){
+       unsigned int gpio;
+
+       gpio = ar7240_reg_rd(AR7240_GPIO_IN);
+
+       if(gpio & (1 << GPIO_RST_BUTTON_BIT)){
 #if defined(GPIO_RST_BUTTON_IS_ACTIVE_LOW)
                return(0);
 #else
@@ -343,11 +347,11 @@ const char* print_mem_type(void){
                        break;
 
                case 1:
-                       return " DDR";
+                       return " DDR 16-bit";
                        break;
 
                case 2:
-                       return " DDR2";
+                       return " DDR2 16-bit";
                        break;
 
                default:
index 7b13bc36ad8f51b8da6d8c83f1c3d0dac88a5adf..6960d8cbb15dafd3342a42cdb68daae2c689884d 100755 (executable)
 #include <asm/addrspace.h>
 #include <ar7240_soc.h>
 
-    .globl hornet_pll_init
+       .globl hornet_pll_init
        .text
        .align 4
 
-#define CLEAR_BIT(val, bit)    ((val) & ~(1 << (bit)))
-#define SET_BIT(val, bit)      ((val) |  (1 << (bit)))
+#define CLEAR_BIT(val, bit)                            ((val) & ~(1 << (bit)))
+#define SET_BIT(val, bit)                              ((val) |  (1 << (bit)))
 
 #define CLEAR_PLL_POWER_DOWN(reg_val)  CLEAR_BIT(reg_val, 30)
+#define SET_PLL_POWER_DOWN(reg_val)            SET_BIT(reg_val, 30)
 #define SET_AHB_DIV_TO_4(reg_val)              SET_BIT(SET_BIT(reg_val, 15), 16)
 #define CLEAR_PLL_BYPASS(reg_val)              CLEAR_BIT(reg_val, 2)
+#define SET_PLL_BYPASS(reg_val)                        SET_BIT(reg_val, 2)
 
 /*
  * Helper macros.
  * These Clobber t7, t8 and t9
- */ 
-/*     or  t8, t8, t9;                                 \ */
-#define set_reg(_reg, _val)                         \
-    li  t7, KSEG1ADDR(_reg);                        \
-    lw  t8, 0(t7);                                  \
-    li  t9, _val;                                   \
-    sw  t9, 0(t7);
+ * or  t8, t8, t9;
+ */
+#define set_reg(_reg, _val) \
+       li t7, KSEG1ADDR(_reg); \
+       lw t8, 0(t7);           \
+       li t9, _val;            \
+       sw t9, 0(t7);
+
+/* if reset button is active low -> use bne (branch on not equal) */
+#ifdef GPIO_RST_BUTTON_IS_ACTIVE_LOW
+       #define recovery_jump(_branch) \
+               bne t1, (1 << GPIO_RST_BUTTON_BIT), _branch;
+#else
+       #define recovery_jump(_branch) \
+               beq t1, (1 << GPIO_RST_BUTTON_BIT), _branch;
+#endif
 
 hornet_pll_init:
 
 #if 1
-/* These three wlan reset will avoid original issue, so full chip reset isn't needed here. */
-       set_reg(0xb806001c, 0x00c06b30)
+/* These three wlan reset will avoid original issue,
+ * so full chip reset isn't needed here.
+ *
+ * WLAN_RESET in RST_RESET (AR7240_RESET) register
+ * 0x00C06B30 -> BIT(11) is set
+ * 0x00C06330 -> BIT(11) is not set
+ */
+       set_reg(AR7240_RESET, 0x00C06B30)
        nop
-       set_reg(0xb806001c, 0x00c06330)
+       set_reg(AR7240_RESET, 0x00C06330)
        nop
-       set_reg(0xb806001c, 0x00c06b30)
+       set_reg(AR7240_RESET, 0x00C06B30)
        nop
-       set_reg(0xb806001c, 0x00c06330)
+       set_reg(AR7240_RESET, 0x00C06330)
        nop
 
 reset_wlan:
-       set_reg(0xb806001c, 0x00c06b30)
+       set_reg(AR7240_RESET, 0x00C06B30)
        nop
-       set_reg(0xb806001c, 0x00c06330)
+       set_reg(AR7240_RESET, 0x00C06330)
        nop
-       li  t5, 0x20
+       li t5, 0x20
 
 check_val:
-       beq zero, t5, reset_wlan
-       addi t5, t5, -1
-       li  t6, 0xb80600ac
-       lw  t7, 0(t6)
-       li  t8, 0x10
-       and t7, t7, t8
-       bne zero, t7, check_val
-       set_reg(HORNET_BOOTSTRAP_STATUS, 0x0002110e)
+       beq  zero, t5, reset_wlan
+       addi t5,   t5, -1
+       li   t6,   KSEG1ADDR(HORNET_BOOTSTRAP_STATUS)
+       lw   t7,   0(t6)
+       li   t8,   0x10
+       and  t7,   t7, t8
+       bne  zero, t7, check_val
+       set_reg(HORNET_BOOTSTRAP_STATUS, 0x0002110E)
        nop
 #else
 /* clear wlan reset bit in RESET_Register 0x1c */
-       set_reg(AR7240_RESET, 0x00c06b30)
+       set_reg(AR7240_RESET, 0x00C06B30)
        nop
-       set_reg(AR7240_RESET, 0x00c06330)
+       set_reg(AR7240_RESET, 0x00C06330)
        nop
 
 /* cleck bootstrap status, wait for bit4 on, then clear bit16 */
 wait_loop0:
-       li  t6, KSEG1ADDR(HORNET_BOOTSTRAP_STATUS)
-       lw  t7, 0(t6)
-       li  t8, 0x10
-       and t7, t7, t8
+       li  t6,   KSEG1ADDR(HORNET_BOOTSTRAP_STATUS)
+       lw  t7,   0(t6)
+       li  t8,   0x10
+       and t7,   t7, t8
        bne zero, t7, wait_loop0
        nop
-       set_reg(HORNET_BOOTSTRAP_STATUS, 0x0002110e)
+       set_reg(HORNET_BOOTSTRAP_STATUS, 0x0002110E)
        nop
 #endif
 
 /* RTC reset */
-       set_reg(0x1810704c, 0x00000003)
+/* 0x1810704C -> RTC_FORCE_WAKE (RTC Force Wake) */
+       set_reg(0x1810704C, 0x00000003)
        nop
        nop
+/* 0x18107040 -> RTC_RESET (RTC Reset and Force Sleep and Force Wakeup) */
        set_reg(0x18107040, 0x00000000)
        nop
        nop
@@ -87,6 +106,7 @@ wait_loop0:
        nop
 
 wait_loop1:
+/* 0x18107044 -> RTC_STATUS (RTC Sleep Status) */
        li  t6, KSEG1ADDR(0x18107044)
        lw  t7, 0(t6)
        li  t8, 0x2
@@ -94,32 +114,32 @@ wait_loop1:
        bne t8, t7, wait_loop1
        nop
 
-/* AHB/APH reset */
 /*
- * TODO: something is wrong here!
- * 0x18104000 is "Reset the Host Interface (HOST_INTF_RESET_CONTROL)" and bits 0:7 are RESERVED!
+ * AHB/APH reset
+ * TODO: 0x18104000 is "Reset the Host Interface (HOST_INTF_RESET_CONTROL)" and bits 0:7 are RESERVED!
  */
+/*
        set_reg(0x18104000, 0x00000003)
        nop
        set_reg(0x18104000, 0x00000000)
        nop
-
-/* MAC reset */
+*/
 /*
- * TODO: same here - something is wrong here!
- * "RTC registers occupy the offset range 0x18107000–0x18107FFC in the AR9331 address space."
+ * MAC reset (TODO: ?? AR9344 has 0x18107000 register -> AR9344_RTC_BASE)
  */
+/*
        set_reg(0x18107000, 0x0000000F)
        nop
        set_reg(0x18107000, 0x00000000)
        nop
+*/
 
 #if 1  /* fetch pmu1.refv and ctrl2.tx from OTP */
-       li  t1, KSEG1ADDR(0x18114014)
-       lw  t2, 0(t1)
+       li t1, KSEG1ADDR(0x18114014)
+       lw t2, 0(t1)
 
 otp_loop0:
-       li  t3, KSEG1ADDR(0x18115f18)
+       li  t3, KSEG1ADDR(0x18115F18)
        lw  t4, 0(t3)
        nop
        li  t5, 0x7
@@ -127,7 +147,7 @@ otp_loop0:
        li  t5, 0x4
        bne t4, t5, otp_loop0
        nop
-       li  t6, KSEG1ADDR(0x18115f1c)
+       li  t6, KSEG1ADDR(0x18115F1C)
        lw  t7, 0(t6)
        nop
        li  t8, 0x80000080
@@ -139,7 +159,7 @@ otp_loop0_end:
        lw  t2, 0(t1)
 
 otp_loop1:
-       li  t3, KSEG1ADDR(0x18115f18)
+       li  t3, KSEG1ADDR(0x18115F18)
        lw  t4, 0(t3)
        nop
        li  t5, 0x7
@@ -147,7 +167,7 @@ otp_loop1:
        li  t5, 0x4
        bne t4, t5, otp_loop1
        nop
-       li  t6, KSEG1ADDR(0x18115f1c)
+       li  t6, KSEG1ADDR(0x18115F1C)
        lw  t7, 0(t6)
        nop
        li  t8, 0x80000080
@@ -157,18 +177,17 @@ default_pmu:
        li  t5, 0x80                    /* default 0x031c4386 */
        bne t8, t9, otp_end
 
-otp_loop1_end:
 fetch_otp:
        srl t8, t7, 0x18
        li  t1, 0xf
-       and t2, t1 , t7                 /* USB */
-       and t5, t1 , t8                 /* PMU */
+       and t2, t1, t7                  /* USB */
+       and t5, t1, t8                  /* PMU */
 
 check_pmu:
-       li t0, 0x4                              /* PMU range should be 0x4~0xa */
+       li  t0, 0x4                             /* PMU range should be 0x4~0xa */
        bgt t0, t5, default_pmu
        nop
-       li t0, 0xa                              /* PMU range should be 0x4~0xa */
+       li  t0, 0xa                             /* PMU range should be 0x4~0xa */
        blt t0, t5, default_pmu
        nop
        li  t0, 0x4
@@ -179,92 +198,93 @@ otp_end:
 
 #if 1 /* Program PMU */
 #define PMU_TEST_NO 1000
-       li  t6, KSEG1ADDR(0x18116c40)
-       li  t9, 0xbd000010
-       li  t0, 0
-       li  t1, 0
-       li  t2, 0
-       li  t3, PMU_TEST_NO
-       sw  t3, 12(t9)
+       li t6, KSEG1ADDR(0x18116C40)
+       li t9, 0xbd000010
+       li t0, 0
+       li t1, 0
+       li t2, 0
+       li t3, PMU_TEST_NO
+       sw t3, 12(t9)
 
 pmu_loop0:
-       beq zero, t3, pmu_loop0_end
+       beq   zero, t3, pmu_loop0_end
        nop
-       addi t3, t3, -1
-       li  t7, 0x10180000  /* ldo_tune 0x3 */
+       addi  t3,   t3, -1
+       li    t7,   0x10180000  /* ldo_tune 0x3 */
        nop
-       sw  t7, 4(t6)
+       sw    t7,   4(t6)
        nop
-       lw  t8, 4(t6)
+       lw    t8,   4(t6)
        nop
-       beq t8, t7, pmu_loop0_end
+       beq   t8,   t7, pmu_loop0_end
        nop
-       addiu  t0, t0, 1
-       b   pmu_loop0
+       addiu t0,   t0, 1
+       b     pmu_loop0
        nop
 
 pmu_loop0_end:
-       li  t3, PMU_TEST_NO
+       li t3, PMU_TEST_NO
 
 pmu_loop1:
-       beq zero, t3, pmu_loop1_end
+       beq  zero, t3, pmu_loop1_end
        nop
-       addi t3, t3, -1
-       //li  t7, 0x031c4326    /* 1.100V */
-       //li  t7, 0x031c4336    /* 1.125V */
-       //li  t7, 0x031c4346    /* 1.150V */
-       //li  t7, 0x031c4356    /* 1.175V */
-       //li  t7, 0x031c4366    /* 1.200V */
-       //li  t7, 0x031c4376    /* 1.225V */
-       li  t7, 0x031c4386    /* 1.250V (DEFAULT) */
-       //li  t7, 0x031c4396    /* 1.275V */
-       //li  t7, 0x031c43a6    /* 1.300V */
+       addi t3,   t3, -1
+       //li   t7,   0x031c4326    /* 1.100V */
+       //li   t7,   0x031c4336    /* 1.125V */
+       //li   t7,   0x031c4346    /* 1.150V */
+       //li   t7,   0x031c4356    /* 1.175V */
+       //li   t7,   0x031c4366    /* 1.200V */
+       //li   t7,   0x031c4376    /* 1.225V */
+       li   t7,   0x031c4386    /* 1.250V (DEFAULT) */
+       //li   t7,   0x031c4396    /* 1.275V */
+       //li   t7,   0x031c43a6    /* 1.300V */
        nop
 
 #if 1 /* from OTP */
-       li  t8, 0xffffff0f
+       li  t8, 0xFFFFFF0F
        and t7, t7, t8
        or  t7, t7, t5
 #endif
-       sw  t7, 0(t6)
+       sw    t7, 0(t6)
        nop
-       lw  t8, 0(t6)
+       lw    t8, 0(t6)
        nop
-       beq t8, t7, pmu_loop1_end
+       beq   t8, t7, pmu_loop1_end
        nop
-       addiu  t1, t1, 1
-       b   pmu_loop1
+       addiu t1, t1, 1
+       b     pmu_loop1
        nop
 
 pmu_loop1_end:
-       li  t3, PMU_TEST_NO
+       li t3, PMU_TEST_NO
 
 pmu_loop2:
-       beq zero, t3, pmu_loop2_end
+       beq   zero, t3, pmu_loop2_end
        nop
-       addi t3, t3, -1
-       li  t7, 0x10380000  /* ldo_tune 0x3 */
+       addi  t3,   t3, -1
+       li    t7,   0x10380000  /* ldo_tune 0x3 */
        nop
-       sw  t7, 4(t6)
+       sw    t7,   4(t6)
        nop
-       lw  t8, 4(t6)
+       lw    t8,   4(t6)
        nop
-       beq t8, t7, pmu_loop2_end
+       beq   t8,   t7, pmu_loop2_end
        nop
-       addiu  t2, t2, 1
-       b   pmu_loop2
+       addiu t2,   t2, 1
+       b     pmu_loop2
        nop
 
 pmu_loop2_end:
-       sw  t0, 0(t9)
+       sw t0, 0(t9)
        nop
-       sw  t1, 4(t9)
+       sw t1, 4(t9)
        nop
-       sw  t2, 8(t9)
+       sw t2, 8(t9)
        nop
 #endif
 
 #if 1 /* Program ki, kd */
+// TODO: ??
 /* Program ki/kd */
 #if CONFIG_40MHZ_XTAL_SUPPORT
        set_reg(0x18116244, 0x19e82f01)
@@ -285,88 +305,152 @@ pmu_loop2_end:
 #endif
 
 /* max AHB Master wait time out ... */
-//     set_reg(0xb800009c, 0xfffff)
-//     nop
+       set_reg(0x1800009C, 0xfffff)
+       nop
+
+/*
+ * O/C recovery mode
+ *
+ * If RESET BUTTON is pressed and hold during power on
+ * we will use default PLL and clocks configuration (400/400/200)
+ *
+ * Using t0 and t1 (t1 indicates if recovery mode was turned on)
+ */
+pll_clock_control_oc_recovery:
+       li  t0, KSEG1ADDR(AR7240_GPIO_IN)
+       lw  t1, 0(t0)
+       and t1, t1, (1 << GPIO_RST_BUTTON_BIT)
+       recovery_jump(pll_clock_control_default)
+       nop
+
+#if defined(PLL_IN_FLASH_MAGIC_OFFSET)
+/*
+ * PLL and CLOCK configuration from FLASH
+ *
+ * Using t0, t2 and t3 (t2 stores magic value from flash)
+ */
+pll_clock_control_flash:
+       li  t0, (CFG_FLASH_BASE + PLL_IN_FLASH_DATA_BLOCK_OFFSET + PLL_IN_FLASH_MAGIC_OFFSET)   // load PLL_IN_FLASH_MAGIC address
+       lw  t2, 0(t0)                                                                                                                                                   // load PLL_IN_FLASH_MAGIC value from FLASH
+       bne t2, PLL_IN_FLASH_MAGIC, pll_clock_control                                                                                   // jump if we don't have PLL_MAGIC value in FLASH
+       nop
+       lw  t3, 8(t0)                                                                                                                                                   // load CLOCK_CONTROL register value from FLASH
+       or  t3, t3, 0x18004                                                                                                                                             // set BYPASS bit and make AHB_POST_DIV = 4
+       li  t0, KSEG1ADDR(AR7240_CPU_CLOCK_CONTROL)                                                                                             // load CLOCK_CONTROL register address
+       sw  t3, 0(t0)                                                                                                                                                   // store value in CLOCK_CONTROL register
+       j   pll_settle_time                                                                                                                                             // jump to pll_settle_time
+       nop
+#endif
 
+pll_clock_control:
 /* set PLL bypass(Bit 2), CPU_POST_DIV, DDR_POST_DIV, AHB_POST_DIV in CPU clock control */
 /* in some cases, the SoC doesn't start with higher clock on AHB */
-       set_reg(AR7240_CPU_CLOCK_CONTROL, SET_AHB_DIV_TO_4(CPU_CLK_CONTROL_VAL))
+       set_reg(AR7240_CPU_CLOCK_CONTROL, SET_AHB_DIV_TO_4(SET_PLL_BYPASS(CPU_CLK_CONTROL_VAL)))
+       j pll_settle_time
        nop
 
+pll_clock_control_default:
+/* set PLL bypass(Bit 2), CPU_POST_DIV, DDR_POST_DIV, AHB_POST_DIV in CPU clock control */
+/* in some cases, the SoC doesn't start with higher clock on AHB */
+       set_reg(AR7240_CPU_CLOCK_CONTROL, SET_AHB_DIV_TO_4(SET_PLL_BYPASS(CPU_CLK_CONTROL_VAL_DEFAULT)))
+       nop
+
+pll_settle_time:
 /* set SETTLE_TIME in CPU PLL */
        set_reg(AR7240_USB_PLL_CONFIG, CPU_PLL_SETTLE_TIME_VAL)
        nop
 
-/* read GPIO_SET register */
-       li  t0, KSEG1ADDR(AR7240_GPIO_IN)
-       lw  t1, 0(t0)
-       and t1, t1, (1 << GPIO_RST_BUTTON_BIT)
-       beq     t1,     (1 << GPIO_RST_BUTTON_BIT), pll_default_unlock_handler
+pll_unlock_handler_oc_recovery:
+       recovery_jump(pll_unlock_handler_default)
        nop
 
+#if defined(PLL_IN_FLASH_MAGIC_OFFSET)
+pll_unlock_handler_flash:
+       bne t2, PLL_IN_FLASH_MAGIC, pll_unlock_handler                                                                                  // jump if we don't have PLL_MAGIC value in FLASH
+       nop
+       li  t0, (CFG_FLASH_BASE + PLL_IN_FLASH_DATA_BLOCK_OFFSET + PLL_IN_FLASH_MAGIC_OFFSET)   // load PLL_IN_FLASH_MAGIC address
+       lw  t3, 4(t0)                                                                                                                                                   // load CPU_PLL_CONFIG register value from FLASH
+       or  t3, t3, 0x40000000                                                                                                                                  // set CPU_PLLPWD bit (power down for CPU PLL)
+       li  t0, KSEG1ADDR(AR7240_CPU_PLL_CONFIG)                                                                                                // load CPU_PLL_CONFIG register address
+       sw  t3, 0(t0)                                                                                                                                                   // store value in CPU_PLL_CONFIG register
+       j   wait_loop2                                                                                                                                                  // jump to wait_loop2
+       nop
+#endif
+
 pll_unlock_handler:
 /* set nint, frac, refdiv, outdiv, range in CPU PLL configuration resiter */
-       set_reg(AR7240_CPU_PLL_CONFIG, CPU_PLL_CONFIG_VAL)
-       j       wait_loop2
+       set_reg(AR7240_CPU_PLL_CONFIG, SET_PLL_POWER_DOWN(CPU_PLL_CONFIG_VAL))
+       j wait_loop2
        nop
 
-pll_default_unlock_handler:
+pll_unlock_handler_default:
 /* set nint, frac, refdiv, outdiv, range in CPU PLL configuration resiter */
-       set_reg(AR7240_CPU_PLL_CONFIG, CPU_PLL_CONFIG_VAL_DEFAULT)
+       set_reg(AR7240_CPU_PLL_CONFIG, SET_PLL_POWER_DOWN(CPU_PLL_CONFIG_VAL_DEFAULT))
        nop
 
 wait_loop2:
-       li  t6, KSEG1ADDR(AR7240_CPU_PLL_CONFIG)
-       lw  t7, 0(t6)
-       li  t8, 0x80000000
-       and t7, t7, t8
+       li  t6,   KSEG1ADDR(AR7240_CPU_PLL_CONFIG)
+       lw  t7,   0(t6)
+       li  t8,   0x80000000
+       and t7,   t7, t8
        bne zero, t7, wait_loop2
        nop
     
 /* put frac bit19:10 configuration */
+/* TODO: do we need this? */
        set_reg(AR7240_PCIE_PLL_CONFIG, CPU_PLL_DITHER_FRAC_VAL)
        nop
 
-/* read GPIO_SET register */
-       li  t0, KSEG1ADDR(AR7240_GPIO_IN)
-       lw  t1, 0(t0)
-       and t1, t1, (1 << GPIO_RST_BUTTON_BIT)
-       beq     t1,     (1 << GPIO_RST_BUTTON_BIT), pll_default_lock_handler
+pll_lock_handler_oc_recovery:
+       recovery_jump(pll_lock_handler_default)
        nop
 
+#if defined(PLL_IN_FLASH_MAGIC_OFFSET)
+pll_lock_handler_flash:
+       bne t2, PLL_IN_FLASH_MAGIC, pll_lock_handler                                                                                    // jump if we don't have PLL_MAGIC value in FLASH
+       nop
+       li  t0, (CFG_FLASH_BASE + PLL_IN_FLASH_DATA_BLOCK_OFFSET + PLL_IN_FLASH_MAGIC_OFFSET)   // load PLL_IN_FLASH_MAGIC address
+       lw  t3, 4(t0)                                                                                                                                                   // load CPU_PLL_CONFIG register value from FLASH
+       li  t0, KSEG1ADDR(AR7240_CPU_PLL_CONFIG)                                                                                                // load CPU_PLL_CONFIG register address
+       sw  t3, 0(t0)                                                                                                                                                   // store value in CPU_PLL_CONFIG register
+       j   wait_loop3                                                                                                                                                  // jump to wait_loop3
+       nop
+#endif
+
 pll_lock_handler:
-/* clear PLL power down bit in CPU PLLl configuration */
-       set_reg(AR7240_CPU_PLL_CONFIG, CLEAR_PLL_POWER_DOWN(CPU_PLL_CONFIG_VAL))
-       j       wait_loop3
+/* clear PLL power down bit in CPU PLL configuration */
+       set_reg(AR7240_CPU_PLL_CONFIG, CPU_PLL_CONFIG_VAL)
+       j wait_loop3
        nop
 
-pll_default_lock_handler:
-/* clear PLL power down bit in CPU PLLl configuration */
-       set_reg(AR7240_CPU_PLL_CONFIG, CLEAR_PLL_POWER_DOWN(CPU_PLL_CONFIG_VAL_DEFAULT))
+pll_lock_handler_default:
+/* clear PLL power down bit in CPU PLL configuration */
+       set_reg(AR7240_CPU_PLL_CONFIG, CPU_PLL_CONFIG_VAL_DEFAULT)
        nop
 
 wait_loop3:
-       li  t6, KSEG1ADDR(AR7240_CPU_PLL_CONFIG)
-       lw  t7, 0(t6)
-       li  t8, 0x80000000
-       and t7, t7, t8
+/* wait for PLL update -> bit 31 in CPU_PLL_CONFIG should be 0 */
+       li  t6,   KSEG1ADDR(AR7240_CPU_PLL_CONFIG)
+       lw  t7,   0(t6)
+       li  t8,   0x80000000
+       and t7,   t7, t8
        bne zero, t7, wait_loop3
        nop
 
 /* confirm DDR PLL lock */
-       li  t3, 100
-       li  t4, 0
+       li t3, 100
+       li t4, 0
 
 start_meas0:
        addi t4, t4, 1
-       bgt t4, t3, pll_unlock_handler
+       bgt  t4, t3, pll_unlock_handler_oc_recovery
        nop
-       li  t5, 5
+       li   t5, 5
 
 start_meas:
        li  t6, KSEG1ADDR(0x18116248)
        lw  t7, 0(t6)
-       li  t8, 0xbfffffff
+       li  t8, 0xBFFFFFFF
        and t7, t7, t8
        sw  t7, 0(t6)
        nop
@@ -375,46 +459,72 @@ start_meas:
        li t9, 10
 
 delayloop0:
-       subu t9, t9, 1
-       bne t9, zero, delayloop0
+       subu t9, t9,   1
+       bne  t9, zero, delayloop0
        nop
-       li  t8, 0x40000000
-       or  t7, t7, t8
-       sw  t7, 0(t6)
+       li   t8, 0x40000000
+       or   t7, t7,   t8
+       sw   t7, 0(t6)
        nop
 
 meas_done_statue:
-       li  t6, KSEG1ADDR(0x1811624c)
-       lw  t7, 0(t6)
-       li  t8, 0x8
-       and t7, t7, t8
+       li  t6,   KSEG1ADDR(0x1811624C)
+       lw  t7,   0(t6)
+       li  t8,   0x8
+       and t7,   t7, t8
        beq zero, t7, meas_done_statue
        nop
 
 meas_result:
-       li  t6, KSEG1ADDR(0x18116248)
-       lw  t7, 0(t6)
-       li  t8, 0x007ffff8
-       and t7, t7, t8
-       srl t7, t7, 3
-       li  t8, 0x4000
-       bgt t7, t8, start_meas0
+       li   t6,   KSEG1ADDR(0x18116248)
+       lw   t7,   0(t6)
+       li   t8,   0x007FFFF8
+       and  t7,   t7, t8
+       srl  t7,   t7, 3
+       li   t8,   0x4000
+       bgt  t7,   t8, start_meas0
+       nop
+       addi t5,   t5, -1
+       bne  zero, t5, start_meas
        nop
-       addi t5, t5, -1
-       bne zero, t5, start_meas
+
+pll_clear_bypass_oc_recovery:
+       recovery_jump(pll_clear_bypass_default)
        nop
 
+#if defined(PLL_IN_FLASH_MAGIC_OFFSET)
+pll_clear_bypass_flash:
+       bne t2, PLL_IN_FLASH_MAGIC, pll_clear_bypass                                                                                    // jump if we don't have PLL_MAGIC value in FLASH
+       nop
+       li  t0, (CFG_FLASH_BASE + PLL_IN_FLASH_DATA_BLOCK_OFFSET + PLL_IN_FLASH_MAGIC_OFFSET)   // load PLL_IN_FLASH_MAGIC address
+       lw  t3, 8(t0)                                                                                                                                                   // load CLOCK_CONTROL register value from FLASH
+       li  t0, KSEG1ADDR(AR7240_CPU_CLOCK_CONTROL)                                                                                             // load CLOCK_CONTROL register address
+       sw  t3, 0(t0)                                                                                                                                                   // store value in CLOCK_CONTROL register
+       j   end                                                                                                                                                                 // jump to end
+       nop
+#endif
+
+pll_clear_bypass:
+/* clear PLL bypass (bit 2) in CPU CLOCK CONTROL register */
+       set_reg(AR7240_CPU_CLOCK_CONTROL, CPU_CLK_CONTROL_VAL)
+       j end
+       nop
+
+pll_clear_bypass_default:
 /* clear PLL bypass (bit 2) in CPU CLOCK CONTROL register */
-       set_reg(AR7240_CPU_CLOCK_CONTROL, CLEAR_PLL_BYPASS(CPU_CLK_CONTROL_VAL))
+       set_reg(AR7240_CPU_CLOCK_CONTROL, CPU_CLK_CONTROL_VAL_DEFAULT)
        nop
 
-/* Sync mode , Set Bit 8 of DDR Tap Conrtol 3 register */
+/* Sync mode, Set Bit 8 of DDR Tap Conrtol 3 register */
 /*
  * TODO: something is wrong here?
  * There is no AR7240_DDR_TAP_CONTROL3 in AR9331 datasheet!
  */
-       //set_reg(AR7240_DDR_TAP_CONTROL3, 0x10105);
-       //nop
+/*
+       set_reg(AR7240_DDR_TAP_CONTROL3, 0x10105);
+       nop
+*/
 
+end:
        jr ra
        nop
index d5473dde95f453e6b377b7dc204854711becf63f..8eda8e407a68fb4676dd3abd84654cf1c38c6b93 100755 (executable)
@@ -79,6 +79,14 @@ static void flash_set_geom(int size, int sector_count, int sector_size){
 
 unsigned long flash_init(void){
        flash_info_t *info;
+#if defined(PLL_IN_FLASH_MAGIC_OFFSET)
+       u32 pll_magic, spi_control;
+
+       pll_magic = ar7240_reg_rd(CFG_FLASH_BASE + PLL_IN_FLASH_DATA_BLOCK_OFFSET + PLL_IN_FLASH_MAGIC_OFFSET);
+
+       // read SPI CONTROL Configuration register (SPI_CONTROL) value stored in FLASH (PLL_IN_FLASH_MAGIC_OFFSET + 12)
+       spi_control = ar7240_reg_rd(CFG_FLASH_BASE + PLL_IN_FLASH_DATA_BLOCK_OFFSET + PLL_IN_FLASH_MAGIC_OFFSET + 12);
+#endif
 
        info = &flash_info[0];
 
@@ -89,7 +97,16 @@ unsigned long flash_init(void){
        if(reset_button_status()){
                ar7240_reg_wr(AR7240_SPI_CLOCK, AR7240_SPI_CONTROL_DEFAULT);
        } else {
-               ar7240_reg_wr(AR7240_SPI_CLOCK, AR7240_SPI_CONTROL);
+#if defined(PLL_IN_FLASH_MAGIC_OFFSET)
+               // do we have PLL_MAGIC in FLASH?
+               if(pll_magic == PLL_IN_FLASH_MAGIC){
+                       ar7240_reg_wr(AR7240_SPI_CLOCK, spi_control);
+               } else {
+#endif
+                       ar7240_reg_wr(AR7240_SPI_CLOCK, AR7240_SPI_CONTROL);
+#if defined(PLL_IN_FLASH_MAGIC_OFFSET)
+               }
+#endif
        }
 
        ar7240_reg_wr(AR7240_SPI_FS,    0x0);
index f9c662cc16b31656054d791183cff28d23464588..4d52f94a4a00fe6a227d60a00a0af4588ded0379 100755 (executable)
@@ -791,7 +791,7 @@ unsigned int s26_rd_phy(unsigned int phy_addr, unsigned int reg_addr){
                i++;
 
                if(i > 824)     {
-                       //printf("## Error: MDIO_BUSY!\n");
+                       printf("## Error: MDIO_BUSY!\n");
                        break;
                }
 
@@ -807,6 +807,7 @@ unsigned int s26_rd_phy(unsigned int phy_addr, unsigned int reg_addr){
 
 void s26_wr_phy(unsigned int phy_addr, unsigned int reg_addr, unsigned int write_data){
        unsigned int rddata;
+       unsigned int i = 0;
 
        // MDIO_CMD is set for read
        rddata = athrs26_reg_read(0x98);
@@ -818,6 +819,14 @@ void s26_wr_phy(unsigned int phy_addr, unsigned int reg_addr, unsigned int write
 
        // Check MDIO_BUSY status
        while(rddata){
+               // TODO: do we need this?
+               i++;
+
+               if(i > 824)     {
+                       printf("## Error: MDIO_BUSY!\n");
+                       break;
+               }
+
                rddata = athrs26_reg_read(0x98);
                rddata = rddata & (1 << 31);
        }
index b791cdbbcf8a48c9494d81fe463b205a3e0c2a70..0dc763c0f88b586208b5c73b39e82d4eb9ec2c1b 100755 (executable)
        .align 4
        
 lowlevel_init:
-       set_bb_pll(DPLL2_ADDRESS_c4, 0x13210f00);
-       set_bb_pll(DPLL3_ADDRESS_c8, 0x03000000);
-       set_bb_pll(DPLL2_ADDRESS_44, 0x13210f00);
-       set_bb_pll(DPLL3_ADDRESS_48, 0x03000000);
-       set_bb_pll(DPLL3_ADDRESS_88, 0x03000000);
+       set_bb_pll(DPLL2_ADDRESS_c4, 0x13210f00);       // 0x181161c4 (AR934X_SRIF_CPU_DPLL2_REG)
+       set_bb_pll(DPLL3_ADDRESS_c8, 0x03000000);       // 0x181161c8 (AR934X_SRIF_CPU_DPLL3_REG)
+       set_bb_pll(DPLL2_ADDRESS_44, 0x13210f00);       // 0x18116244 (AR934X_SRIF_DDR_DPLL2_REG)
+       set_bb_pll(DPLL3_ADDRESS_48, 0x03000000);       // 0x18116248 (AR934X_SRIF_DDR_DPLL3_REG)
+       set_bb_pll(DPLL3_ADDRESS_88, 0x03000000);       // 0x18116188 (??)
 
 setup_ref40_val:
        li      t5,     CPU_PLL_CONFIG_NINT_VAL_40
index aca094f7cf969be034c5e64d74315f6a9e33ee71..26fe6d9b8849713699d32aef27bc52c6620d50f3 100755 (executable)
@@ -127,8 +127,32 @@ long int initdram(){
 }\r
 \r
 /*\r
- * TODO: Returns a string with memory type preceded by a space sign\r
+ * Returns a string with memory type preceded by a space sign\r
  */\r
 const char* print_mem_type(void){\r
-       return "";\r
+       unsigned int reg;\r
+\r
+       reg = ar7240_reg_rd(WASP_BOOTSTRAP_REG);\r
+\r
+       // if SDRAM is disabled -> we are using DDR\r
+       if(reg & WASP_BOOTSTRAP_SDRAM_DISABLE_MASK){\r
+\r
+               // 1 -> DDR1\r
+               if(reg & WASP_BOOTSTRAP_DDR_SELECT_MASK){\r
+                       if(reg & WASP_BOOTSTRAP_DDR_WIDTH_MASK){\r
+                               return " DDR 32-bit";\r
+                       } else {\r
+                               return " DDR 16-bit";\r
+                       }\r
+               } else {\r
+                       if(reg & WASP_BOOTSTRAP_DDR_WIDTH_MASK){\r
+                               return " DDR2 32-bit";\r
+                       } else {\r
+                               return " DDR2 16-bit";\r
+                       }\r
+               }\r
+\r
+       } else {\r
+               return " SDRAM";\r
+       }\r
 }\r
index 20189bb1eb65c7d2a0550bf85ad4b290421714e2..95697af13da0c6c5fe3c035b6493e6f9956b0340 100755 (executable)
@@ -1,7 +1,7 @@
 /*
  * (C) Copyright 2013
  * Piotr Dymacz (pepe2k), Real Time Systems, piotr@realtimesystems.pl, pepe2k@gmail.com
- * Custom commands for TP-Link U-Boot 1.1.4 modification.
+ * Custom commands for U-Boot 1.1.4 modification.
  *
  * See file CREDITS for list of people who contributed to U-Boot project.
  *
 
 #include <common.h>
 #include <command.h>
+#include <asm/mipsregs.h>
+#include <asm/addrspace.h>
+#include <ar7240_soc.h>
+#include "../board/ar7240/common/ar7240_flash.h"
+
+extern void ar7240_sys_frequency(u32 *cpu_freq, u32 *ddr_freq, u32 *ahb_freq);
 
 #if defined(OFFSET_MAC_ADDRESS)
 /*
  */
 int do_print_mac(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]){
        char buffer[6];
-#ifdef OFFSET_MAC_ADDRESS2
+#if defined(OFFSET_MAC_ADDRESS2)
        char buffer2[6];
 #endif
 
-#ifdef OFFSET_MAC_ADDRESS2
+#if defined(OFFSET_MAC_ADDRESS2)
        // get MAC1 and MAC2 addresses from flash and print them
        memcpy(buffer,  (void *)(CFG_FLASH_BASE + OFFSET_MAC_DATA_BLOCK + OFFSET_MAC_ADDRESS),  6);
        memcpy(buffer2, (void *)(CFG_FLASH_BASE + OFFSET_MAC_DATA_BLOCK + OFFSET_MAC_ADDRESS2), 6);
@@ -54,7 +60,11 @@ int do_print_mac(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]){
        return(0);
 }
 
-U_BOOT_CMD(printmac, 1, 1, do_print_mac, "print MAC address(es) stored in flash\n", NULL);
+#if defined(OFFSET_MAC_ADDRESS2)
+U_BOOT_CMD(printmac, 1, 1, do_print_mac, "print MAC addresses stored in flash\n", NULL);
+#else
+U_BOOT_CMD(printmac, 1, 1, do_print_mac, "print MAC address stored in flash\n", NULL);
+#endif
 
 /*
  * Change MAC address(es)
@@ -66,7 +76,7 @@ int do_set_mac(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]){
 
        // allow only 2 arg (command name + mac), second argument length should be 17 (xx:xx:xx:xx:xx:xx)
        if(argc != 2 || strlen(argv[1]) != 17){
-#ifdef CFG_LONGHELP
+#if defined(CFG_LONGHELP)
                if(cmdtp->help != NULL){
                        printf("Usage:\n%s %s\n", cmdtp->name, cmdtp->help);
                } else {
@@ -86,15 +96,7 @@ int do_set_mac(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]){
        }
 
        if(j != 5){
-#ifdef CFG_LONGHELP
-               if(cmdtp->help != NULL){
-                       printf("Usage:\n%s %s\n", cmdtp->name, cmdtp->help);
-               } else {
-                       printf("Usage:\n%s %s\n", cmdtp->name, cmdtp->usage);
-               }
-#else
-               printf("Usage:\n%s %s\n", cmdtp->name, cmdtp->usage);
-#endif
+               puts("## Error: given MAC address has wrong format (should be: xx:xx:xx:xx:xx:xx)!\n");
                return(1);
        }
 
@@ -102,11 +104,13 @@ int do_set_mac(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]){
        data_pointer = (unsigned char *)WEBFAILSAFE_UPLOAD_RAM_ADDRESS;
 
        if(!data_pointer){
-               printf("## Error: couldn't allocate RAM for data block backup!\n");
+               puts("## Error: couldn't allocate RAM for data block backup!\n");
                return(1);
        }
 
-       memcpy((void *)data_pointer, (void *)(CFG_FLASH_BASE + OFFSET_MAC_DATA_BLOCK + OFFSET_MAC_ADDRESS), OFFSET_MAC_DATA_BLOCK_LENGTH);
+       puts("** Notice: you should always make a backup of your device\n           entire FLASH content before making any changes\n\n");
+
+       memcpy((void *)data_pointer, (void *)(CFG_FLASH_BASE + OFFSET_MAC_DATA_BLOCK), OFFSET_MAC_DATA_BLOCK_LENGTH);
 
        // store new MAC address in RAM
        for(i = 0; i < 6; i++){
@@ -212,3 +216,322 @@ int do_erase_env(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]){
 
 U_BOOT_CMD(eraseenv, 1, 1, do_erase_env, "erase environment sector in flash\n", NULL);
 #endif /* if defined(CONFIG_FOR_8DEVICES_CARAMBOLA2) */
+
+#if defined(CONFIG_MACH_HORNET)
+// TODO: AR9344 support
+/*
+ * Show current CPU/RAM/AHB/SPI/REF clocks
+ */
+int do_print_clocks(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]){
+       unsigned int ahb_freq, ddr_freq, cpu_freq, spi_freq;
+#if defined(PLL_IN_FLASH_MAGIC_OFFSET)
+       unsigned int pll, ref, reg;
+#endif
+
+       // read clocks
+       ar7240_sys_frequency(&cpu_freq, &ddr_freq, &ahb_freq);
+
+       // calculate SPI clock (we need to set bit 0 to 1 in SPI_FUNC_SELECT to access SPI registers)
+       ar7240_reg_wr(AR7240_SPI_FS, 0x01);
+       spi_freq = ahb_freq / (((ar7240_reg_rd(AR7240_SPI_CLOCK) & 0x3F) + 1) * 2);
+       ar7240_reg_wr(AR7240_SPI_FS, 0x0);
+
+       // make MHz from Hz
+       cpu_freq /= 1000000;
+       ddr_freq /= 1000000;
+       ahb_freq /= 1000000;
+       spi_freq /= 1000000;
+
+       printf("Current clocks (approximated):\n- CPU: %3d MHz\n", cpu_freq);
+       printf("- RAM: %3d MHz\n", ddr_freq);
+       printf("- AHB: %3d MHz\n", ahb_freq);
+       printf("- SPI: %3d MHz\n", spi_freq);
+
+#if defined(PLL_IN_FLASH_MAGIC_OFFSET)
+       if(ar7240_reg_rd(HORNET_BOOTSTRAP_STATUS) & HORNET_BOOTSTRAP_SEL_25M_40M_MASK){
+               ref = 40000000;
+       } else {
+               ref = 25000000;
+       }
+
+       // do we have PLL_MAGIC in FLASH?
+       reg = ar7240_reg_rd(CFG_FLASH_BASE + PLL_IN_FLASH_DATA_BLOCK_OFFSET + PLL_IN_FLASH_MAGIC_OFFSET);
+
+       if(reg == PLL_IN_FLASH_MAGIC){
+               puts("\nClocks configuration stored in FLASH (approximated):\n");
+
+               // read CPU PLL Configuration register (CPU_PLL_CONFIG) value stored in FLASH (PLL_IN_FLASH_MAGIC_OFFSET + 4)
+               reg = ar7240_reg_rd(CFG_FLASH_BASE + PLL_IN_FLASH_DATA_BLOCK_OFFSET + PLL_IN_FLASH_MAGIC_OFFSET + 4);
+
+               // refdiv
+               pll = ref / ((reg & HORNET_PLL_CONFIG_REFDIV_MASK) >> HORNET_PLL_CONFIG_REFDIV_SHIFT);
+
+               // div_int
+               pll *= ((reg & HORNET_PLL_CONFIG_NINT_MASK) >> HORNET_PLL_CONFIG_NINT_SHIFT);
+
+               // outdiv
+               pll >>= ((reg & HORNET_PLL_CONFIG_OUTDIV_MASK) >> HORNET_PLL_CONFIG_OUTDIV_SHIFT);
+
+               // read CLOCK CONTROL Configuration register (CLOCK_CONTROL) value stored in FLASH (PLL_IN_FLASH_MAGIC_OFFSET + 8)
+               reg = ar7240_reg_rd(CFG_FLASH_BASE + PLL_IN_FLASH_DATA_BLOCK_OFFSET + PLL_IN_FLASH_MAGIC_OFFSET + 8);
+
+               // cpu, ram, ahb
+               cpu_freq = pll / (((reg & HORNET_CLOCK_CONTROL_CPU_POST_DIV_MASK) >> HORNET_CLOCK_CONTROL_CPU_POST_DIV_SHIFT) + 1);
+               ddr_freq = pll / (((reg & HORNET_CLOCK_CONTROL_DDR_POST_DIV_MASK) >> HORNET_CLOCK_CONTROL_DDR_POST_DIV_SFIFT) + 1);
+               ahb_freq = pll / (((reg & HORNET_CLOCK_CONTROL_AHB_POST_DIV_MASK) >> HORNET_CLOCK_CONTROL_AHB_POST_DIV_SFIFT) + 1);
+
+               // read SPI CONTROL Configuration register (SPI_CONTROL) value stored in FLASH (PLL_IN_FLASH_MAGIC_OFFSET + 12)
+               reg = ar7240_reg_rd(CFG_FLASH_BASE + PLL_IN_FLASH_DATA_BLOCK_OFFSET + PLL_IN_FLASH_MAGIC_OFFSET + 12);
+
+               // spi
+               spi_freq = ahb_freq / (2 * ((reg & 0x3F) + 1));
+
+               // make MHz from Hz
+               cpu_freq /= 1000000;
+               ddr_freq /= 1000000;
+               ahb_freq /= 1000000;
+               spi_freq /= 1000000;
+
+               printf("- CPU: %3d MHz\n", cpu_freq);
+               printf("- RAM: %3d MHz\n", ddr_freq);
+               printf("- AHB: %3d MHz\n", ahb_freq);
+               printf("- SPI: %3d MHz\n", spi_freq);
+       } else {
+               puts("\nPLL and clocks configuration in FLASH is empty,\nuse 'setclocks' to set them and store in FLASH.\n");
+       }
+#endif
+
+       if(ar7240_reg_rd(HORNET_BOOTSTRAP_STATUS) & HORNET_BOOTSTRAP_SEL_25M_40M_MASK){
+               puts("\nReference clock: 40 MHz\n");
+       } else {
+               puts("\nReference clock: 25 MHz\n");
+       }
+
+       return(0);
+}
+
+U_BOOT_CMD(printclocks, 1, 1, do_print_clocks, "print CPU, RAM, AHB, SPI and REF clocks\n", NULL);
+#endif /* #if defined(CONFIG_MACH_HORNET) */
+
+#if defined(PLL_IN_FLASH_MAGIC_OFFSET)
+/*
+ * Set and store PLL configuration in FLASH
+ */
+int do_set_clocks(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]){
+       unsigned int outdiv, range, refdiv, divint, cpu_div, ram_div, ahb_div, spi_div;
+       unsigned int cpu_pll_config_reg_val = 0;
+       unsigned int clock_control_reg_val  = 0;
+       unsigned int spi_control_reg_val    = 0;
+       unsigned char *data_pointer;
+       int i;
+       char buf[128];
+
+       // allow only 9 arg (command name + range refdiv divint outdiv cpu_div ram_div ahb_div spi_div)
+       if(argc != 9){
+               puts("** Notice: you should always make a backup of your device\n           entire FLASH content before making any changes\n\n");
+
+#ifdef CFG_LONGHELP
+               if(cmdtp->help != NULL){
+                       printf("Usage:\n%s %s\n", cmdtp->name, cmdtp->help);
+               } else {
+                       printf("Usage:\n%s %s\n", cmdtp->name, cmdtp->usage);
+               }
+#else
+               printf("Usage:\n%s %s\n", cmdtp->name, cmdtp->usage);
+#endif
+               return(1);
+       }
+
+       // range validation
+       range = simple_strtoul(argv[1], NULL, 10);
+
+       if(range != 1 && range != 0){
+               puts("## Error: range should be 0 or 1!\n");
+               return(1);
+       }
+
+       // refdiv validation (5 bits)
+       refdiv = simple_strtoul(argv[2], NULL, 10);
+
+       if(refdiv > 31 || refdiv < 1){
+               puts("## Error: refdiv should be in range 1..31!\n");
+               return(1);
+       }
+
+       // divint validation (6 bits)
+       divint = simple_strtoul(argv[3], NULL, 10);
+
+       if(divint > 63 || divint < 1){
+               puts("## Error: divint should be in range 1..63!\n");
+               return(1);
+       }
+
+       // outdiv validation (3 bits)
+       outdiv = simple_strtoul(argv[4], NULL, 10);
+
+       if(outdiv > 7 || outdiv < 1){
+               puts("## Error: outdiv should be in range 1..7!\n");
+               return(1);
+       }
+
+       // cpu_div validation (2 bits)
+       cpu_div = simple_strtoul(argv[5], NULL, 10);
+
+       if(cpu_div > 4 || cpu_div < 1){
+               puts("## Error: cpu_div should be in range 1..4!\n");
+               return(1);
+       }
+
+       // ram_div validation (2 bits)
+       ram_div = simple_strtoul(argv[6], NULL, 10);
+
+       if(ram_div > 4 || ram_div < 1){
+               puts("## Error: ram_div should be in range 1..4!\n");
+               return(1);
+       }
+
+       // ahb_div validation (2 bits)
+       ahb_div = simple_strtoul(argv[7], NULL, 10);
+
+       if(ahb_div > 4 || ahb_div < 1){
+               puts("## Error: ahb_div should be in range 1..4!\n");
+               return(1);
+       }
+
+       // spi_div validation (6 bits)
+       spi_div = simple_strtoul(argv[8], NULL, 10);
+
+       if(spi_div > 128 || spi_div < 4 || (spi_div % 2)){
+               puts("## Error: spi_div should be even and in range 4..128!\n");
+               return(1);
+       }
+
+       // SPI CLK = (AHB_CLK / ((CLOCK_DIVIDER + 1) * 2)),
+       // spi_div = 2 * (CLOCK_DIVIDER + 1)
+       // we need CLOCK_DIVIDER:
+       spi_div /= 2;
+       spi_div--;
+
+       puts("Calculated registers values:\n");
+
+       // calculate registers values
+       // MAKE_CPU_PLL_CONFIG_VAL(divint, refdiv, range, outdiv)
+       cpu_pll_config_reg_val = (unsigned int)(MAKE_CPU_PLL_CONFIG_VAL(divint, refdiv, range, outdiv));
+       printf("- CPU_PLL_CONFIG: 0x%08X\n", cpu_pll_config_reg_val);
+
+       // MAKE_CPU_CLK_CONTROL_VAL(cpudiv, ddrdiv, ahbdiv)
+       clock_control_reg_val = (unsigned int)(MAKE_CPU_CLK_CONTROL_VAL(cpu_div, ram_div, ahb_div));
+       printf("- CLOCK_CONTROL:  0x%08X\n", clock_control_reg_val);
+
+       // SPI_CONTROL
+       spi_control_reg_val = (unsigned int)(0x40 | spi_div);
+       printf("- SPI_CONTROL:    0x%08X\n\n", spi_control_reg_val);
+
+       // backup entire block in which we store PLL/CLK settings
+       data_pointer = (unsigned char *)WEBFAILSAFE_UPLOAD_RAM_ADDRESS;
+
+       if(!data_pointer){
+               puts("## Error: couldn't allocate RAM for data block backup!\n");
+               return(1);
+       }
+
+       puts("** Notice: you should always make a backup of your device\n           entire FLASH content before making any changes\n\n");
+
+       memcpy((void *)data_pointer, (void *)(CFG_FLASH_BASE + PLL_IN_FLASH_DATA_BLOCK_OFFSET), PLL_IN_FLASH_DATA_BLOCK_LENGTH);
+
+       // save PLL_IN_FLASH_MAGIC
+       for(i = 0; i < 4; i++){
+               data_pointer[PLL_IN_FLASH_MAGIC_OFFSET + i] = 0xFF & (PLL_IN_FLASH_MAGIC >> (8 * (3 - i)));
+       }
+
+       // save CPU_PLL_CONFIG
+       for(i = 0; i < 4; i++){
+               data_pointer[PLL_IN_FLASH_MAGIC_OFFSET + 4 + i] = 0xFF & (cpu_pll_config_reg_val >> (8 * (3 - i)));
+       }
+
+       // save CLOCK_CONTROL
+       for(i = 0; i < 4; i++){
+               data_pointer[PLL_IN_FLASH_MAGIC_OFFSET + 8 + i] = 0xFF & (clock_control_reg_val >> (8 * (3 - i)));
+       }
+
+       // save SPI_CONTROL
+       for(i = 0; i < 4; i++){
+               data_pointer[PLL_IN_FLASH_MAGIC_OFFSET + 12 + i] = 0xFF & (spi_control_reg_val >> (8 * (3 - i)));
+       }
+
+       // erase FLASH, copy data from RAM
+       sprintf(buf,
+                       "erase 0x%lX +0x%lX; cp.b 0x%lX 0x%lX 0x%lX",
+                       CFG_FLASH_BASE + PLL_IN_FLASH_DATA_BLOCK_OFFSET,
+                       PLL_IN_FLASH_DATA_BLOCK_LENGTH,
+                       WEBFAILSAFE_UPLOAD_RAM_ADDRESS,
+                       CFG_FLASH_BASE + PLL_IN_FLASH_DATA_BLOCK_OFFSET,
+                       PLL_IN_FLASH_DATA_BLOCK_LENGTH);
+
+       printf("Executing: %s\n\n", buf);
+
+       return(run_command(buf, 0));
+}
+
+U_BOOT_CMD(setclocks, 9, 0, do_set_clocks, "set PLL and clocks configuration in FLASH\n",
+               "range refdiv divint outdiv cpu_div ram_div ahb_div spi_div\n"
+               "\t- calculates and stores CPU_PLL_CONFIG and CLOCK_CONTROL registers in FLASH\n"
+               "\t- default configuration for 400/400/200/33 MHz:\n"
+               "\t  0 1 32 1 1 1 2 6 (25 MHz ref, PLL -> ((25 / 1) * 32) / (1 / 2 ^ 1) = 400 MHz)\n"
+               "\t  0 1 20 1 1 1 2 6 (40 MHz ref, PLL -> ((40 / 1) * 20) / (1 / 2 ^ 1) = 400 MHz)\n\n"
+               "\t- formulas for PLL and clocks calculations:\n"
+               "\t  PLL = ((ref / refdiv) * divint) / (1 / (2 ^ outdiv))\n"
+               "\t  CPU = PLL / cpu_div\n"
+               "\t  RAM = PLL / ram_div\n"
+               "\t  AHB = PLL / ahb_div\n"
+               "\t  SPI = AHB / spi_div\n\n"
+               "\t  *ref - reference clock (25 or 40 MHz)\n");
+
+/*
+ * Remove (clear) PLL and clock settings in FLASH
+ */
+int do_clear_clocks(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]){
+       unsigned char *data_pointer;
+       int i;
+       char buf[128];
+       unsigned int reg = 0;
+
+       // do we have PLL_MAGIC in FLASH?
+       reg = ar7240_reg_rd(CFG_FLASH_BASE + PLL_IN_FLASH_DATA_BLOCK_OFFSET + PLL_IN_FLASH_MAGIC_OFFSET);
+
+       if(reg == PLL_IN_FLASH_MAGIC){
+               // backup entire block in which we store PLL/CLK settings
+               data_pointer = (unsigned char *)WEBFAILSAFE_UPLOAD_RAM_ADDRESS;
+
+               if(!data_pointer){
+                       puts("## Error: couldn't allocate RAM for data block backup!\n");
+                       return(1);
+               }
+
+               memcpy((void *)data_pointer, (void *)(CFG_FLASH_BASE + PLL_IN_FLASH_DATA_BLOCK_OFFSET), PLL_IN_FLASH_DATA_BLOCK_LENGTH);
+
+               // 16 bytes (4x 32-bit values)
+               for(i = 0; i < 16; i++){
+                       data_pointer[PLL_IN_FLASH_MAGIC_OFFSET + i] = 0xFF;
+               }
+
+               // erase FLASH, copy data from RAM
+               sprintf(buf,
+                               "erase 0x%lX +0x%lX; cp.b 0x%lX 0x%lX 0x%lX",
+                               CFG_FLASH_BASE + PLL_IN_FLASH_DATA_BLOCK_OFFSET,
+                               PLL_IN_FLASH_DATA_BLOCK_LENGTH,
+                               WEBFAILSAFE_UPLOAD_RAM_ADDRESS,
+                               CFG_FLASH_BASE + PLL_IN_FLASH_DATA_BLOCK_OFFSET,
+                               PLL_IN_FLASH_DATA_BLOCK_LENGTH);
+
+               printf("Executing: %s\n\n", buf);
+
+               return(run_command(buf, 0));
+       } else {
+               puts("** Warning: there is no PLL and clocks configuration in FLASH!\n");
+               return(1);
+       }
+}
+
+U_BOOT_CMD(clearclocks, 1, 0, do_clear_clocks, "remove PLL and clocks configuration from FLASH\n", NULL);
+#endif /* #if defined(PLL_IN_FLASH_MAGIC_OFFSET) */
index d6d9ead8bc3ebd561ce3a9c5f685b1eb633dc598..155e4d0f95c3ae0c021b6d7cf0174440c1533a8d 100755 (executable)
@@ -194,7 +194,7 @@ void env_relocate(void){
                //puts("Using default environment\n\n");
 #else
                puts("** Warning: bad env CRC, using default,\n"
-                        "   use 'saveenv' to save it in flash\n\n");
+                        "   use 'saveenv' to save it in FLASH\n\n");
 #endif
 
                if(sizeof(default_environment) > ENV_SIZE){
index ced70b6d08f6e4dfb87dec7217082898865fc3e3..66d42a9d7cb8a42f123dc00255e11ac8469b17fa 100755 (executable)
@@ -46,6 +46,8 @@ extern int athr_phy_speed(int unit);
 extern void athr_reg_init(void);
 #endif
 
+//#define AG7240_DEBUG
+
 static int ag7240_send(struct eth_device *dev, volatile void *packet, int length) {
        int i;
 
@@ -474,7 +476,7 @@ static void ag7240_get_ethaddr(struct eth_device *dev) {
                mac[4] = 0x0b;
                mac[5] = 0xad;
 
-               printf("## Error: MAC address stored in flash is invalid!\nUsing fixed address!\n");
+               printf("## Error: MAC address in FLASH is invalid, using fixed!\n");
        }
 #else
        // 00-03-7F (Atheros Communications, Inc.)
@@ -493,7 +495,9 @@ int ag7240_enet_initialize(bd_t * bis) {
        u32 mask, mac_h, mac_l;
        int i;
 
-       //printf("ag7240_enet_initialize...\n");
+#ifdef AG7240_DEBUG
+       printf("ag7240_enet_initialize...\n");
+#endif
 
        // TODO check this register!
        ar7240_reg_wr(HORNET_BOOTSTRAP_STATUS, ar7240_reg_rd(HORNET_BOOTSTRAP_STATUS) & ~HORNET_BOOTSTRAP_MDIO_SLAVE_MASK);
@@ -518,12 +522,12 @@ int ag7240_enet_initialize(bd_t * bis) {
        for (i = 0; i < CFG_AG7240_NMACS; i++) {
 
                if ((dev[i] = (struct eth_device *) malloc(sizeof(struct eth_device))) == NULL) {
-                       puts("malloc failed\n");
+                       puts("## Error: malloc failed\n");
                        return 0;
                }
 
                if ((ag7240_macs[i] = (ag7240_mac_t *) malloc(sizeof(ag7240_mac_t))) == NULL) {
-                       puts("malloc failed\n");
+                       puts("## Error: malloc failed\n");
                        return 0;
                }
 
@@ -587,8 +591,10 @@ int ag7240_enet_initialize(bd_t * bis) {
                        udelay(100 * 1000);
                }
 
-               //unsigned char *mac = dev[i]->enetaddr;
-               //printf("\nInterface %s MAC address: %02X:%02X:%02X:%02X:%02X:%02X\n", dev[i]->name, mac[0] & 0xff, mac[1] & 0xff, mac[2] & 0xff, mac[3] & 0xff, mac[4] & 0xff, mac[5] & 0xff);
+#ifdef AG7240_DEBUG
+               unsigned char *mac = dev[i]->enetaddr;
+               printf("\nInterface %s MAC address: %02X:%02X:%02X:%02X:%02X:%02X\n", dev[i]->name, mac[0] & 0xff, mac[1] & 0xff, mac[2] & 0xff, mac[3] & 0xff, mac[4] & 0xff, mac[5] & 0xff);
+#endif
 
                mac_l = (dev[i]->enetaddr[4] << 8) | (dev[i]->enetaddr[5]);
                mac_h = (dev[i]->enetaddr[0] << 24) | (dev[i]->enetaddr[1] << 16) | (dev[i]->enetaddr[2] << 8) | (dev[i]->enetaddr[3] << 0);
@@ -607,34 +613,49 @@ int ag7240_enet_initialize(bd_t * bis) {
 #endif
                        {
 #ifdef CFG_ATHRS26_PHY
-                               //printf("s26 reg init \n");
+       #ifdef AG7240_DEBUG
+                               printf("s26 reg init \n");
+       #endif
                                athrs26_reg_init();
 #endif
 #ifdef CFG_ATHRS27_PHY
-                               //printf("s27 reg init \n");
+       #ifdef AG7240_DEBUG
+                               printf("s27 reg init \n");
+       #endif
                                athrs27_reg_init();
 #endif
 #ifdef CONFIG_F1E_PHY
-                               //printf("F1Phy reg init \n");
+       #ifdef AG7240_DEBUG
+                               printf("F1Phy reg init \n");
+       #endif
                                athr_reg_init();
 #endif
                        }
                } else {
 #ifdef CFG_ATHRS26_PHY
-                       //printf("athrs26_reg_init_lan\n");
+       #ifdef AG7240_DEBUG
+                       printf("athrs26_reg_init_lan\n");
+       #endif
                        athrs26_reg_init_lan();
 #endif
 #ifdef CFG_ATHRS27_PHY
-                       //printf("s27 reg init lan \n");
+       #ifdef AG7240_DEBUG
+                       printf("s27 reg init lan \n");
+       #endif
                        athrs27_reg_init_lan();
 #endif
                }
 
-               //printf("ag7240_phy_setup\n");
+#ifdef AG7240_DEBUG
+               printf("ag7240_phy_setup\n");
+#endif
                //udelay(100*1000);
 
                ag7240_phy_setup(ag7240_macs[i]->mac_unit);
-               //printf("Interface %s is up\n", dev[i]->name);
+
+#ifdef AG7240_DEBUG
+               printf("Interface %s is up\n", dev[i]->name);
+#endif
        }
 
        return 1;
index 14b8c1ce8524ac2c633cc0fcc2ed955d5f67ca44..64e47281e2d2ae47cda001125b9b4accbd782fd0 100755 (executable)
@@ -542,7 +542,7 @@ static void ag7240_get_ethaddr(struct eth_device *dev){
                mac[4] = 0x0b;\r
                mac[5] = 0xad;\r
 \r
-               printf("## Error: MAC address stored in flash is invalid!\nUsing fixed address!\n");\r
+               printf("## Error: MAC address in FLASH is invalid, using fixed!\n");\r
        }\r
 #else\r
        // 00-03-7F (Atheros Communications, Inc.)\r
index be910757d7e03ce5679c4a45d8d3190b1736d630..0d68f9c2a24491b88948dd20b600876e1828a1de 100755 (executable)
 #define         UART16550_READ(y)              ar7240_reg_rd((AR7240_UART_BASE+y))\r
 #define         UART16550_WRITE(x, z)  ar7240_reg_wr((AR7240_UART_BASE+x), z)\r
 \r
+/*\r
+ * Get CPU, RAM and AHB clocks\r
+ * Based on: Linux/arch/mips/ath79/clock.c\r
+ */\r
 void ar7240_sys_frequency(u32 *cpu_freq, u32 *ddr_freq, u32 *ahb_freq){\r
+#ifdef CONFIG_WASP\r
+       u32 ref_rate, pll, out_div, ref_div, nint, nfrac, frac, clk_ctrl, postdiv, cpu_pll, ddr_pll;\r
+\r
+       // determine reference clock (25 or 40 MHz)\r
+       pll = ar7240_reg_rd(RST_BOOTSTRAP_ADDRESS);\r
+\r
+       if(pll & 0x10){ // bit 4 == 1 -> REF_CLK == 40 MHz\r
+               ref_rate = 40000000;\r
+       } else {\r
+               ref_rate = 25000000;\r
+       }\r
+\r
+       pll = ar7240_reg_rd(DPLL2_ADDRESS_c4);\r
+\r
+       // CPU PLL from SRIF?\r
+       if(pll & (1 << 30)){\r
+\r
+               out_div = (pll >> 13) & 0x7;\r
+               pll = ar7240_reg_rd(0x181161c0);\r
+               nint = (pll >> 18) & 0x1ff;\r
+               //nfrac = pll & 0x0003ffff;\r
+               ref_div = (pll >> 27) & 0x1f;\r
+               //frac = 1 << 18;\r
+\r
+       } else {\r
+               // only for tests\r
+               // TODO: fix me\r
+               *cpu_freq = 560000000;\r
+               *ddr_freq = 400000000;\r
+               *ahb_freq = 200000000;\r
+               return;\r
+       }\r
+\r
+       cpu_pll = (ref_rate / ref_div) * nint;\r
+       cpu_pll /= (1 << out_div);\r
+\r
+       // DDR PLL from SRIF?\r
+       pll = ar7240_reg_rd(DPLL2_ADDRESS_44);\r
+\r
+       if (pll & (1 << 30)) {\r
+\r
+               out_div = (pll >> 13) & 0x7;\r
+               pll = ar7240_reg_rd(0x18116240);\r
+               nint = (pll >> 18) & 0x1ff;\r
+               //nfrac = pll & 0x0003ffff;\r
+               ref_div = (pll >> 27) & 0x1f;\r
+               //frac = 1 << 18;\r
+\r
+       } else {\r
+               // only for tests\r
+               // TODO: fix me\r
+               *cpu_freq = 560000000;\r
+               *ddr_freq = 400000000;\r
+               *ahb_freq = 200000000;\r
+               return;\r
+       }\r
+\r
+       ddr_pll = (ref_rate / ref_div) * nint;\r
+       ddr_pll /= (1 << out_div);\r
+\r
+       clk_ctrl = ar7240_reg_rd(AR934X_CPU_DDR_CLOCK_CONTROL);\r
+\r
+       postdiv = (clk_ctrl >> 5) & 0x1f;\r
+\r
+       // CPU CLK\r
+       if(clk_ctrl & (1 << 2)){                        // CPU_PLL_BYPASS\r
+               *cpu_freq = ref_rate;\r
+       } else if(clk_ctrl & (1 << 20)){        // CPU CLK is derived from CPU_PLL\r
+               *cpu_freq = cpu_pll / (postdiv + 1);\r
+       } else {                                                        // CPU CLK is derived from DDR_PLL\r
+               *cpu_freq = ddr_pll / (postdiv + 1);\r
+       }\r
+\r
+       postdiv = (clk_ctrl >> 10) & 0x1f;\r
+\r
+       // DDR CLK\r
+       if(clk_ctrl & (1 << 3)){                        // DDR_PLL_BYPASS\r
+               *ddr_freq = ref_rate;\r
+       } else if(clk_ctrl & (1 << 21)){        // DDR CLK is derived from DDR_PLL\r
+               *ddr_freq = ddr_pll / (postdiv + 1);\r
+       } else {                                                        // DDR CLK is derived from CPU_PLL\r
+               *ddr_freq = cpu_pll / (postdiv + 1);\r
+       }\r
+\r
+       postdiv = (clk_ctrl >> 15) & 0x1f;\r
+\r
+       // AHB CLK\r
+       if(clk_ctrl & (1 << 4)){                        // AHB_PLL_BYPASS\r
+               *ahb_freq = ref_rate;\r
+       } else if(clk_ctrl & (1 << 24)){        // AHB CLK is derived from DDR_PLL\r
+               *ahb_freq = ddr_pll / (postdiv + 1);\r
+       } else {                                                        // AHB CLK is derived from CPU_PLL\r
+               *ahb_freq = cpu_pll / (postdiv + 1);\r
+       }\r
+\r
+#else\r
     u32 pll, pll_div, ref_div, ahb_div, ddr_div, freq;\r
 \r
     pll = ar7240_reg_rd(AR7240_CPU_PLL_CONFIG);\r
@@ -52,12 +152,11 @@ void ar7240_sys_frequency(u32 *cpu_freq, u32 *ddr_freq, u32 *ahb_freq){
     if(ahb_freq){\r
                *ahb_freq = freq/ahb_div;\r
        }\r
+#endif\r
 }\r
 \r
 int serial_init(void){\r
        u32 div, val;\r
-       u32 ahb_freq, ddr_freq, cpu_freq;\r
-\r
 #ifdef CONFIG_WASP\r
        val = ar7240_reg_rd(WASP_BOOTSTRAP_REG);\r
 \r
@@ -67,6 +166,8 @@ int serial_init(void){
                div = (40 * 1000000) / (16 * CONFIG_BAUDRATE);\r
        }\r
 #else\r
+       u32 ahb_freq, ddr_freq, cpu_freq;\r
+\r
        ar7240_sys_frequency(&cpu_freq, &ddr_freq, &ahb_freq);\r
 \r
        div = ahb_freq/(16 * CONFIG_BAUDRATE);\r
index f7f15ca9c6ca0b73126efff0a831c0d946dabbb0..436ee0793af88e68b663253c2cf32fd5035f0971 100755 (executable)
@@ -6,27 +6,27 @@
 #define uart_reg_read(x)        ar7240_reg_rd( (AR7240_UART_BASE+x) )
 #define uart_reg_write(x, y)    ar7240_reg_wr( (AR7240_UART_BASE+x), y)
 
-static int AthrUartGet(char *__ch_data) {
+static int AthrUartGet(char *__ch_data){
        u32 rdata;
 
        rdata = uart_reg_read(UARTDATA_ADDRESS);
 
-       if (UARTDATA_UARTRXCSR_GET(rdata)) {
-               *__ch_data = (char) UARTDATA_UARTTXRXDATA_GET(rdata);
+       if(UARTDATA_UARTRXCSR_GET(rdata)){
+               *__ch_data = (char)UARTDATA_UARTTXRXDATA_GET(rdata);
                rdata = UARTDATA_UARTRXCSR_SET(1);
                uart_reg_write(UARTDATA_ADDRESS, rdata);
-               return 1;
+               return(1);
        } else {
-               return 0;
+               return(0);
        }
 }
 
-static void AthrUartPut(char __ch_data) {
+static void AthrUartPut(char __ch_data){
        u32 rdata;
 
        do {
                rdata = uart_reg_read(UARTDATA_ADDRESS);
-       } while (UARTDATA_UARTTXCSR_GET(rdata) == 0);
+       } while(UARTDATA_UARTTXCSR_GET(rdata) == 0);
 
        rdata = UARTDATA_UARTTXRXDATA_SET((u32)__ch_data);
        rdata |= UARTDATA_UARTTXCSR_SET(1);
@@ -38,13 +38,13 @@ static void AthrUartPut(char __ch_data) {
  * Get CPU, RAM and AHB clocks
  * Based on: Linux/arch/mips/ath79/clock.c
  */
-void ar7240_sys_frequency(u32 *cpu_freq, u32 *ddr_freq, u32 *ahb_freq) {
-       u32 ref_rate, clock_ctrl, cpu_config, freq, t;
+void ar7240_sys_frequency(u32 *cpu_freq, u32 *ddr_freq, u32 *ahb_freq){
+       u32 ref_rate, clock_ctrl, cpu_config, pll, temp;
 
        // determine reference clock (25 or 40 MHz)
-       t = ar7240_reg_rd(HORNET_BOOTSTRAP_STATUS);
+       temp = ar7240_reg_rd(HORNET_BOOTSTRAP_STATUS);
 
-       if(t & HORNET_BOOTSTRAP_SEL_25M_40M_MASK){
+       if(temp & HORNET_BOOTSTRAP_SEL_25M_40M_MASK){
                ref_rate = 40000000;
        } else {
                ref_rate = 25000000;
@@ -63,36 +63,37 @@ void ar7240_sys_frequency(u32 *cpu_freq, u32 *ddr_freq, u32 *ahb_freq) {
                cpu_config = ar7240_reg_rd(AR7240_CPU_PLL_CONFIG);
 
                // REFDIV
-               t = (cpu_config & HORNET_PLL_CONFIG_REFDIV_MASK) >> HORNET_PLL_CONFIG_REFDIV_SHIFT;
-               freq = ref_rate / t;
+               temp = (cpu_config & HORNET_PLL_CONFIG_REFDIV_MASK) >> HORNET_PLL_CONFIG_REFDIV_SHIFT;
+               pll = ref_rate / temp;
 
                // DIV_INT (multiplier)
-               t = (cpu_config & HORNET_PLL_CONFIG_NINT_MASK) >> HORNET_PLL_CONFIG_NINT_SHIFT;
-               freq *= t;
+               temp = (cpu_config & HORNET_PLL_CONFIG_NINT_MASK) >> HORNET_PLL_CONFIG_NINT_SHIFT;
+               pll *= temp;
 
                // OUTDIV
-               t = (cpu_config & HORNET_PLL_CONFIG_OUTDIV_MASK) >> HORNET_PLL_CONFIG_OUTDIV_SHIFT;
-               if(t == 0){     // value 0 is not allowed
-                       t = 1;
+               temp = (cpu_config & HORNET_PLL_CONFIG_OUTDIV_MASK) >> HORNET_PLL_CONFIG_OUTDIV_SHIFT;
+
+               if(temp == 0){ // value 0 is not allowed
+                       temp = 1;
                }
 
-               freq >>= t;
+               pll >>= temp;
 
                // CPU clock divider
-               t = ((clock_ctrl & HORNET_CLOCK_CONTROL_CPU_POST_DIV_MASK) >> HORNET_CLOCK_CONTROL_CPU_POST_DIV_SHIFT) + 1;
-               *cpu_freq = freq / t;
+               temp = ((clock_ctrl & HORNET_CLOCK_CONTROL_CPU_POST_DIV_MASK) >> HORNET_CLOCK_CONTROL_CPU_POST_DIV_SHIFT) + 1;
+               *cpu_freq = pll / temp;
 
                // DDR clock divider
-               t = ((clock_ctrl & HORNET_CLOCK_CONTROL_DDR_POST_DIV_MASK) >> HORNET_CLOCK_CONTROL_DDR_POST_DIV_SFIFT) + 1;
-               *ddr_freq = freq / t;
+               temp = ((clock_ctrl & HORNET_CLOCK_CONTROL_DDR_POST_DIV_MASK) >> HORNET_CLOCK_CONTROL_DDR_POST_DIV_SFIFT) + 1;
+               *ddr_freq = pll / temp;
 
                // AHB clock divider
-               t = ((clock_ctrl & HORNET_CLOCK_CONTROL_AHB_POST_DIV_MASK) >> HORNET_CLOCK_CONTROL_AHB_POST_DIV_SFIFT) + 1;
-               *ahb_freq = freq / t;
+               temp = ((clock_ctrl & HORNET_CLOCK_CONTROL_AHB_POST_DIV_MASK) >> HORNET_CLOCK_CONTROL_AHB_POST_DIV_SFIFT) + 1;
+               *ahb_freq = pll / temp;
        }
 }
 
-int serial_init(void) {
+int serial_init(void){
        u32 rdata;
        u32 baudRateDivisor, clock_step;
        u32 fcEnable = 0;
@@ -109,11 +110,10 @@ int serial_init(void) {
        ar7240_reg_wr(AR7240_GPIO_FUNC, rdata);
 
        /* Get reference clock rate, then set baud rate to 115200 */
-       // TODO: check the following code
        rdata = ar7240_reg_rd(HORNET_BOOTSTRAP_STATUS);
        rdata &= HORNET_BOOTSTRAP_SEL_25M_40M_MASK;
 
-       if (rdata) {
+       if(rdata){
                baudRateDivisor = (40000000 / (16 * 115200)) - 1; // 40 MHz clock is taken as UART clock
        } else {
                baudRateDivisor = (25000000 / (16 * 115200)) - 1; // 25 MHz clock is taken as UART clock
@@ -145,27 +145,28 @@ int serial_init(void) {
        return 0;
 }
 
-int serial_tstc(void) {
-       return (UARTDATA_UARTRXCSR_GET(uart_reg_read(UARTDATA_ADDRESS)));
+int serial_tstc(void){
+       return(UARTDATA_UARTRXCSR_GET(uart_reg_read(UARTDATA_ADDRESS)));
 }
 
-u8 serial_getc(void) {
+u8 serial_getc(void){
        char ch_data;
 
-       while (!AthrUartGet(&ch_data))
-               ;
+       while(!AthrUartGet(&ch_data));
 
-       return (u8) ch_data;
+       return((u8)ch_data);
 }
 
-void serial_putc(u8 byte) {
-       if (byte == '\n') AthrUartPut('\r');
+void serial_putc(u8 byte){
+       if (byte == '\n'){
+               AthrUartPut('\r');
+       }
 
-       AthrUartPut((char) byte);
+       AthrUartPut((char)byte);
 }
 
-void serial_puts(const char *s) {
-       while (*s) {
+void serial_puts(const char *s){
+       while(*s){
                serial_putc(*s++);
        }
 }
index 4e0c66aa364963a78f5e98c7e96e2eb5cb915b1a..f4922777c6c51c0e6ec7b2b02a8d141bd149c9db 100755 (executable)
@@ -30,7 +30,7 @@
 #include <asm/addrspace.h>
 #include <ar7240_soc.h>
 
-#define ATH_SPI_CLOCK  0xbf000004
+#define ATH_SPI_CLOCK  0x1F000004
 
 #define RVECENT(f,n) \
    b f; nop
@@ -326,7 +326,9 @@ rel_start:
 #elif defined(CONFIG_WASP_SUPPORT)
        li      t0,     0x243
 #else
-       li      t0,     0x43
+       // TODO: SPI clock from FLASH?
+       // for now we will use divider = 10 ( (4+1)*2 )
+       li      t0,     0x44
 #endif
        sw      t0,     0(a0)
 #endif
index 1e4b8a77e6547a1e46c82272bad47fed74d027e6..b6f04b91d5546c1f291f56fac3619f86509c4da9 100755 (executable)
 #include <version.h>
 #include <asm/regdef.h>
 #include <asm/mipsregs.h>
+#include <asm/addrspace.h>
+#include <ar7240_soc.h>
 
-#define AR7100_SPI_CLOCK  0xbf000004
+#define AR7100_SPI_CLOCK  0x1F000004
 
 #ifdef CONFIG_WASP_SUPPORT
        #define ATH_APB_BASE                            0xB8000000  /* KSEG1ADDR(0x18000000) */
@@ -388,9 +390,10 @@ rel_start:
 
 #if defined(CONFIG_AR7100) || defined(CONFIG_AR7240)
        /* REMAP_DISABLE */
-       // TODO: SPI flash clock?
-       li      a0, AR7100_SPI_CLOCK
-       li      t0, 0x42                // was 0x43
+       // TODO: SPI clock from FLASH?
+       // for now we will use divider = 10 ( (4+1)*2 )
+       li      a0, KSEG1ADDR(AR7100_SPI_CLOCK)
+       li      t0, 0x44
        sw      t0, 0(a0)
 #endif
 
index df04d6fc5f5fcb580d75aca412918a70fe201682..2213b8c33915a8973850c4f566585237a5f6bce6 100755 (executable)
 
 // WASP BootStrap Register
 #define WASP_BOOTSTRAP_REG                                     (AR7240_RESET_BASE + 0xb0)
+#define WASP_BOOTSTRAP_SDRAM_DISABLE_SHIFT     1
+#define WASP_BOOTSTRAP_SDRAM_DISABLE_MASK      (1 << WASP_BOOTSTRAP_SDRAM_DISABLE_SHIFT)
+#define WASP_BOOTSTRAP_DDR_SELECT_SHIFT                0
+#define WASP_BOOTSTRAP_DDR_SELECT_MASK         (1 << WASP_BOOTSTRAP_DDR_SELECT_SHIFT)
+#define WASP_BOOTSTRAP_DDR_WIDTH_SHIFT         21
+#define WASP_BOOTSTRAP_DDR_WIDTH_MASK          (1 << WASP_BOOTSTRAP_DDR_WIDTH_SHIFT)
 #define WASP_REF_CLK_25                                                (1 << 4) /* 0 - 25MHz   1 - 40 MHz */
 #define WASP_RAM_TYPE(a)                                       ((a) & 0x3)
 
index 25c5cd5730fa87395e79e83ae0dc0805ffe7d217..c08e035ebe4f07071e81ae9e2164f583738cde82 100755 (executable)
@@ -32,7 +32,7 @@
 #define _U_BOOT_H_     1
 
 typedef struct bd_info {
-       int                             bi_baudrate;    /* serial console baudrate */
+       unsigned int    bi_baudrate;    /* serial console baudrate */
        unsigned long   bi_ip_addr;             /* IP Address */
        unsigned char   bi_enetaddr[6]; /* Ethernet adress */
        unsigned long   bi_arch_number; /* unique id for this board */
@@ -42,6 +42,7 @@ typedef struct bd_info {
        unsigned long   bi_flashstart;  /* start of FLASH memory */
        unsigned long   bi_flashsize;   /* size  of FLASH memory */
        unsigned long   bi_flashoffset; /* reserved area for startup monitor */
+       unsigned long   bi_cfg_hz;
 } bd_t;
 
 #define bi_env_data bi_env->data
index b04a2d7d0a64d360dea70d947201c3fe9815b326..93ae44149b35272ffed1ecab88706e407b0cf227 100755 (executable)
 #define CONFIG_IPADDR          192.168.1.1
 #define CONFIG_SERVERIP                192.168.1.2
 
-#undef CFG_PLL_FREQ
-#undef CFG_HZ
-#undef CPU_PLL_CONFIG_VAL
-#undef CPU_CLK_CONTROL_VAL
+#undef CFG_HZ
+#define        CFG_HZ                          bd->bi_cfg_hz
+#undef CPU_PLL_CONFIG_VAL
+#undef CPU_CLK_CONTROL_VAL
 
 // CPU-RAM-AHB frequency setting
-#define CFG_PLL_FREQ    CFG_PLL_400_400_200
-//#define CFG_PLL_FREQ CFG_PLL_525_525_262     // only for test!
+#ifndef CFG_PLL_FREQ
+       #define CFG_PLL_FREQ    CFG_PLL_400_400_200
+#endif
 
 /*
  * CPU_PLL_DITHER_FRAC_VAL
  * bits        20..29  NFRAC_STEP      =>      1
  *
  */
-#define CPU_PLL_DITHER_FRAC_VAL                0x001003e8
+#define CPU_PLL_DITHER_FRAC_VAL                0x001003E8
 
 /*
  * CPU_PLL_SETTLE_TIME_VAL
 /*
  * CPU_PLL_CONFIG and CPU_CLK_CONTROL registers values generator
  */
-#define MAKE_CPU_PLL_CONFIG_VAL(divint, refdiv, outdiv)                (0x40000000 | ((0x3F & divint) << 10) | ((0x1F & refdiv) << 16) | ((0x7 & outdiv) << 23))
-#define MAKE_CPU_CLK_CONTROL_VAL(cpudiv, ddrdiv, ahbdiv)       (0x4 | ((0x3 & (cpudiv - 1)) << 5) | ((0x3 & (ddrdiv - 1)) << 10) | ((0x3 & (ahbdiv - 1)) << 15))
+#define MAKE_CPU_PLL_CONFIG_VAL(divint, refdiv, range, outdiv) (((0x3F & divint) << 10) | ((0x1F & refdiv) << 16) | ((0x1 & range) << 21) | ((0x7 & outdiv) << 23))
+#define MAKE_CPU_CLK_CONTROL_VAL(cpudiv, ddrdiv, ahbdiv)               (((0x3 & (cpudiv - 1)) << 5) | ((0x3 & (ddrdiv - 1)) << 10) | ((0x3 & (ahbdiv - 1)) << 15))
 
 /*
  * Default values (400/400/200 MHz) for O/C recovery mode
 #define CPU_CLK_CONTROL_VAL_DEFAULT            MAKE_CPU_CLK_CONTROL_VAL(1, 1, 2)
 
 #if CONFIG_40MHZ_XTAL_SUPPORT
-       // DIV_INT = 20 (40 MHz * 20/2 = 400 MHz)
-       // REFDIV = 1, OUTDIV = 1
-       #define CPU_PLL_CONFIG_VAL_DEFAULT      MAKE_CPU_PLL_CONFIG_VAL(20, 1, 1)
+       // DIV_INT = 20 (40 MHz * 20/2 = 400 MHz), REFDIV = 1, RANGE = 0, OUTDIV = 1
+       #define CPU_PLL_CONFIG_VAL_DEFAULT      MAKE_CPU_PLL_CONFIG_VAL(20, 1, 0, 1)
 #else
-       // DIV_INT = 32 (25 MHz * 32/2 = 400 MHz)
-       // REFDIV = 1, OUTDIV = 1
-       #define CPU_PLL_CONFIG_VAL_DEFAULT      MAKE_CPU_PLL_CONFIG_VAL(32, 1, 1)
+       // DIV_INT = 32 (25 MHz * 32/2 = 400 MHz), REFDIV = 1, RANGE = 0, OUTDIV = 1
+       #define CPU_PLL_CONFIG_VAL_DEFAULT      MAKE_CPU_PLL_CONFIG_VAL(32, 1, 0, 1)
 #endif
 
 // CLOCK_DIVIDER = 2 (SPI clock = 200 / 6 ~ 33 MHz)
 #define AR7240_SPI_CONTROL_DEFAULT     0x42
 
-#if (CFG_PLL_FREQ == CFG_PLL_400_400_200)
-
-       #define CFG_HZ  (400000000LU/2)
+#if (CFG_PLL_FREQ == CFG_PLL_200_200_100)
 
        // CPU_DIV = 1, RAM_DIV = 1, AHB_DIV = 2
        #define CPU_CLK_CONTROL_VAL             MAKE_CPU_CLK_CONTROL_VAL(1, 1, 2)
 
        #if CONFIG_40MHZ_XTAL_SUPPORT
-               // DIV_INT = 20 (40 MHz * 20/2 = 400 MHz)
-               // REFDIV = 1, OUTDIV = 1
-               #define CPU_PLL_CONFIG_VAL      0x40815000
+               // DIV_INT = 20 (40 MHz * 20/4 = 200 MHz), REFDIV = 1, RANGE = 0, OUTDIV = 2
+               #define CPU_PLL_CONFIG_VAL      MAKE_CPU_PLL_CONFIG_VAL(20, 1, 0, 2)
        #else
-               // DIV_INT = 32 (25 MHz * 32/2 = 400 MHz)
-               // REFDIV = 1, OUTDIV = 1
-               #define CPU_PLL_CONFIG_VAL      0x40818000
+               // DIV_INT = 32 (25 MHz * 32/4 = 200 MHz), REFDIV = 1, RANGE = 0, OUTDIV = 2
+               #define CPU_PLL_CONFIG_VAL      MAKE_CPU_PLL_CONFIG_VAL(32, 1, 0, 2)
+       #endif
+
+       // CLOCK_DIVIDER = 1 (SPI clock = 100 / 4 ~ 25 MHz)
+       #define AR7240_SPI_CONTROL              0x41
+
+       #define CFG_HZ_FALLBACK (200000000LU/2)
+
+#elif (CFG_PLL_FREQ == CFG_PLL_200_200_200)
+
+       // CPU_DIV = 1, RAM_DIV = 1, AHB_DIV = 1
+       #define CPU_CLK_CONTROL_VAL             MAKE_CPU_CLK_CONTROL_VAL(1, 1, 1)
+
+       #if CONFIG_40MHZ_XTAL_SUPPORT
+               // DIV_INT = 20 (40 MHz * 20/4 = 200 MHz), REFDIV = 1, RANGE = 0, OUTDIV = 2
+               #define CPU_PLL_CONFIG_VAL      MAKE_CPU_PLL_CONFIG_VAL(20, 1, 0, 2)
+       #else
+               // DIV_INT = 32 (25 MHz * 32/4 = 200 MHz), REFDIV = 1, RANGE = 0, OUTDIV = 2
+               #define CPU_PLL_CONFIG_VAL      MAKE_CPU_PLL_CONFIG_VAL(32, 1, 0, 2)
        #endif
 
        // CLOCK_DIVIDER = 2 (SPI clock = 200 / 6 ~ 33 MHz)
        #define AR7240_SPI_CONTROL              0x42
 
-#elif (CFG_PLL_FREQ == CFG_PLL_412_412_206)
+       #define CFG_HZ_FALLBACK (200000000LU/2)
+
+#elif (CFG_PLL_FREQ == CFG_PLL_225_225_112)
+
+       // CPU_DIV = 1, RAM_DIV = 1, AHB_DIV = 2
+       #define CPU_CLK_CONTROL_VAL             MAKE_CPU_CLK_CONTROL_VAL(1, 1, 2)
+
+       #if CONFIG_40MHZ_XTAL_SUPPORT
+               #define FREQUENCY_NOT_SUPPORTED
+       #else
+               // DIV_INT = 36 (25 MHz * 36/4 = 225 MHz), REFDIV = 1, RANGE = 0, OUTDIV = 2
+               #define CPU_PLL_CONFIG_VAL      MAKE_CPU_PLL_CONFIG_VAL(36, 1, 0, 2)
+       #endif
+
+       // CLOCK_DIVIDER = 1 (SPI clock = 112 / 4 ~ 28 MHz)
+       #define AR7240_SPI_CONTROL              0x41
+
+       #define CFG_HZ_FALLBACK (225000000LU/2)
+
+#elif (CFG_PLL_FREQ == CFG_PLL_225_225_225)
+
+       // CPU_DIV = 1, RAM_DIV = 1, AHB_DIV = 1
+       #define CPU_CLK_CONTROL_VAL             MAKE_CPU_CLK_CONTROL_VAL(1, 1, 1)
+
+       #if CONFIG_40MHZ_XTAL_SUPPORT
+               #define FREQUENCY_NOT_SUPPORTED
+       #else
+               // DIV_INT = 36 (25 MHz * 36/4 = 225 MHz), REFDIV = 1, RANGE = 0, OUTDIV = 2
+               #define CPU_PLL_CONFIG_VAL      MAKE_CPU_PLL_CONFIG_VAL(36, 1, 0, 2)
+       #endif
 
-       #define CFG_HZ  (412500000LU/2)
+       // CLOCK_DIVIDER = 3 (SPI clock = 225 / 8 ~ 28 MHz)
+       #define AR7240_SPI_CONTROL              0x43
+
+       #define CFG_HZ_FALLBACK (225000000LU/2)
+
+#elif (CFG_PLL_FREQ == CFG_PLL_250_250_125)
 
        // CPU_DIV = 1, RAM_DIV = 1, AHB_DIV = 2
        #define CPU_CLK_CONTROL_VAL             MAKE_CPU_CLK_CONTROL_VAL(1, 1, 2)
 
-       // DIV_INT = 33 (25 MHz * 33/2 = 412,5 MHz)
-       // REFDIV = 1, OUTDIV = 1
-       #define CPU_PLL_CONFIG_VAL              0x40818400
+       #if CONFIG_40MHZ_XTAL_SUPPORT
+               // DIV_INT = 25 (40 MHz * 25/4 = 250 MHz), REFDIV = 1, RANGE = 0, OUTDIV = 2
+               #define CPU_PLL_CONFIG_VAL      MAKE_CPU_PLL_CONFIG_VAL(25, 1, 0, 2)
+       #else
+               // DIV_INT = 20 (25 MHz * 20/2 = 250 MHz), REFDIV = 1, RANGE = 0, OUTDIV = 1
+               #define CPU_PLL_CONFIG_VAL      MAKE_CPU_PLL_CONFIG_VAL(20, 1, 0, 1)
+       #endif
+
+       // CLOCK_DIVIDER = 1 (SPI clock = 125 / 4 ~ 31 MHz)
+       #define AR7240_SPI_CONTROL              0x41
+
+       #define CFG_HZ_FALLBACK (250000000LU/2)
+
+#elif (CFG_PLL_FREQ == CFG_PLL_250_250_250)
+
+       // CPU_DIV = 1, RAM_DIV = 1, AHB_DIV = 1
+       #define CPU_CLK_CONTROL_VAL             MAKE_CPU_CLK_CONTROL_VAL(1, 1, 1)
+
+       #if CONFIG_40MHZ_XTAL_SUPPORT
+               // DIV_INT = 25 (40 MHz * 25/4 = 250 MHz), REFDIV = 1, RANGE = 0, OUTDIV = 2
+               #define CPU_PLL_CONFIG_VAL      MAKE_CPU_PLL_CONFIG_VAL(25, 1, 0, 2)
+       #else
+               // DIV_INT = 20 (25 MHz * 20/2 = 250 MHz), REFDIV = 1, RANGE = 0, OUTDIV = 1
+               #define CPU_PLL_CONFIG_VAL      MAKE_CPU_PLL_CONFIG_VAL(20, 1, 0, 1)
+       #endif
 
-       // CLOCK_DIVIDER = 2 (SPI clock = 206,25 / 6 ~ 34,4 MHz)
+       // CLOCK_DIVIDER = 3 (SPI clock = 250 / 8 ~ 31 MHz)
+       #define AR7240_SPI_CONTROL              0x43
+
+       #define CFG_HZ_FALLBACK (250000000LU/2)
+
+#elif (CFG_PLL_FREQ == CFG_PLL_300_300_150)
+
+       // CPU_DIV = 1, RAM_DIV = 1, AHB_DIV = 2
+       #define CPU_CLK_CONTROL_VAL             MAKE_CPU_CLK_CONTROL_VAL(1, 1, 2)
+
+       #if CONFIG_40MHZ_XTAL_SUPPORT
+               // DIV_INT = 15 (40 MHz * 15/2 = 300 MHz), REFDIV = 1, RANGE = 0, OUTDIV = 1
+               #define CPU_PLL_CONFIG_VAL      MAKE_CPU_PLL_CONFIG_VAL(15, 1, 0, 1)
+       #else
+               // DIV_INT = 24 (25 MHz * 24/2 = 300 MHz), REFDIV = 1, RANGE = 0, OUTDIV = 1
+               #define CPU_PLL_CONFIG_VAL      MAKE_CPU_PLL_CONFIG_VAL(24, 1, 0, 1)
+       #endif
+
+       // CLOCK_DIVIDER = 2 (SPI clock = 150 / 6 ~ 25 MHz)
        #define AR7240_SPI_CONTROL              0x42
 
-#elif (CFG_PLL_FREQ == CFG_PLL_425_425_212)
+       #define CFG_HZ_FALLBACK (300000000LU/2)
+
+#elif (CFG_PLL_FREQ == CFG_PLL_325_325_162)
+
+       // CPU_DIV = 1, RAM_DIV = 1, AHB_DIV = 2
+       #define CPU_CLK_CONTROL_VAL             MAKE_CPU_CLK_CONTROL_VAL(1, 1, 2)
+
+       #if CONFIG_40MHZ_XTAL_SUPPORT
+               #define FREQUENCY_NOT_SUPPORTED
+       #else
+               // DIV_INT = 26 (25 MHz * 26/2 = 325 MHz), REFDIV = 1, RANGE = 0, OUTDIV = 1
+               #define CPU_PLL_CONFIG_VAL      MAKE_CPU_PLL_CONFIG_VAL(26, 1, 0, 1)
+       #endif
+
+       // CLOCK_DIVIDER = 2 (SPI clock = 162 / 6 ~ 27 MHz)
+       #define AR7240_SPI_CONTROL              0x42
 
-       #define CFG_HZ  (425000000LU/2)
+       #define CFG_HZ_FALLBACK (325000000LU/2)
+
+#elif (CFG_PLL_FREQ == CFG_PLL_350_350_175)
 
        // CPU_DIV = 1, RAM_DIV = 1, AHB_DIV = 2
        #define CPU_CLK_CONTROL_VAL             MAKE_CPU_CLK_CONTROL_VAL(1, 1, 2)
 
-       // DIV_INT = 34 (25 MHz * 34/2 = 425 MHz)
-       // REFDIV = 1, OUTDIV = 1
-       #define CPU_PLL_CONFIG_VAL              0x40818800
+       #if CONFIG_40MHZ_XTAL_SUPPORT
+               #define FREQUENCY_NOT_SUPPORTED
+       #else
+               // DIV_INT = 28 (25 MHz * 28/2 = 350 MHz), REFDIV = 1, RANGE = 0, OUTDIV = 1
+               #define CPU_PLL_CONFIG_VAL      MAKE_CPU_PLL_CONFIG_VAL(28, 1, 0, 1)
+       #endif
 
-       // CLOCK_DIVIDER = 2 (SPI clock = 212,5 / 6 ~ 35,4 MHz)
+       // CLOCK_DIVIDER = 2 (SPI clock = 175 / 6 ~ 29 MHz)
        #define AR7240_SPI_CONTROL              0x42
 
-#elif (CFG_PLL_FREQ == CFG_PLL_437_437_218)
+       #define CFG_HZ_FALLBACK (350000000LU/2)
 
-       #define CFG_HZ  (437500000LU/2)
+#elif (CFG_PLL_FREQ == CFG_PLL_360_360_180)
 
        // CPU_DIV = 1, RAM_DIV = 1, AHB_DIV = 2
        #define CPU_CLK_CONTROL_VAL             MAKE_CPU_CLK_CONTROL_VAL(1, 1, 2)
 
-       // DIV_INT = 35 (25 MHz * 35/2 = 437,5 MHz)
-       // REFDIV = 1, OUTDIV = 1
-       #define CPU_PLL_CONFIG_VAL              0x40818C00
+       #if CONFIG_40MHZ_XTAL_SUPPORT
+               // DIV_INT = 18 (40 MHz * 18/2 = 360 MHz), REFDIV = 1, RANGE = 0, OUTDIV = 1
+               #define CPU_PLL_CONFIG_VAL      MAKE_CPU_PLL_CONFIG_VAL(18, 1, 0, 1)
+       #else
+               // DIV_INT = 29 (25 MHz * 28/2 = 362 MHz), REFDIV = 1, RANGE = 0, OUTDIV = 1
+               #define CPU_PLL_CONFIG_VAL      MAKE_CPU_PLL_CONFIG_VAL(29, 1, 0, 1)
+       #endif
 
-       // CLOCK_DIVIDER = 2 (SPI clock = 218,75 / 6 ~ 36,5 MHz)
+       // CLOCK_DIVIDER = 2 (SPI clock = 180 / 6 ~ 30 MHz)
        #define AR7240_SPI_CONTROL              0x42
 
+       #define CFG_HZ_FALLBACK (360000000LU/2)
 
-#elif (CFG_PLL_FREQ == CFG_PLL_450_450_225)
+#elif (CFG_PLL_FREQ == CFG_PLL_380_380_190)
+
+       // CPU_DIV = 1, RAM_DIV = 1, AHB_DIV = 2
+       #define CPU_CLK_CONTROL_VAL             MAKE_CPU_CLK_CONTROL_VAL(1, 1, 2)
+
+       #if CONFIG_40MHZ_XTAL_SUPPORT
+               // DIV_INT = 19 (40 MHz * 19/2 = 380 MHz), REFDIV = 1, RANGE = 0, OUTDIV = 1
+               #define CPU_PLL_CONFIG_VAL      MAKE_CPU_PLL_CONFIG_VAL(19, 1, 0, 1)
+       #else
+               #define FREQUENCY_NOT_SUPPORTED
+       #endif
+
+       // CLOCK_DIVIDER = 2 (SPI clock = 190 / 6 ~ 32 MHz)
+       #define AR7240_SPI_CONTROL              0x42
+
+       #define CFG_HZ_FALLBACK (380000000LU/2)
+
+#elif (CFG_PLL_FREQ == CFG_PLL_400_400_200)
+
+       // default configuration
+       #define CPU_CLK_CONTROL_VAL     CPU_CLK_CONTROL_VAL_DEFAULT
+       #define CPU_PLL_CONFIG_VAL      CPU_PLL_CONFIG_VAL_DEFAULT
+       #define AR7240_SPI_CONTROL      AR7240_SPI_CONTROL_DEFAULT
 
-       #define CFG_HZ  (450000000LU/2)
+       #define CFG_HZ_FALLBACK (400000000LU/2)
+
+#elif (CFG_PLL_FREQ == CFG_PLL_412_412_206)
 
        // CPU_DIV = 1, RAM_DIV = 1, AHB_DIV = 2
        #define CPU_CLK_CONTROL_VAL             MAKE_CPU_CLK_CONTROL_VAL(1, 1, 2)
 
-       // DIV_INT = 36 (25 MHz * 36/2 = 450 MHz)
-       // REFDIV = 1, OUTDIV = 1
-       #define CPU_PLL_CONFIG_VAL              0x40819000
+       #if CONFIG_40MHZ_XTAL_SUPPORT
+               #define FREQUENCY_NOT_SUPPORTED
+       #else
+               // DIV_INT = 33 (25 MHz * 33/2 = 412 MHz), REFDIV = 1, RANGE = 0, OUTDIV = 1
+               #define CPU_PLL_CONFIG_VAL      MAKE_CPU_PLL_CONFIG_VAL(33, 1, 0, 1)
+       #endif
 
-       // CLOCK_DIVIDER = 3 (SPI clock = 225 / 6 ~ 37,5 MHz)
+       // CLOCK_DIVIDER = 2 (SPI clock = 206 / 6 ~ 34 MHz)
        #define AR7240_SPI_CONTROL              0x42
 
-#elif (CFG_PLL_FREQ == CFG_PLL_462_462_231)
+       #define CFG_HZ_FALLBACK (412000000LU/2)
 
-       #define CFG_HZ  (462500000LU/2)
+#elif (CFG_PLL_FREQ == CFG_PLL_420_420_210)
 
        // CPU_DIV = 1, RAM_DIV = 1, AHB_DIV = 2
        #define CPU_CLK_CONTROL_VAL             MAKE_CPU_CLK_CONTROL_VAL(1, 1, 2)
 
-       // DIV_INT = 37 (25 MHz * 37/2 = 462,5 MHz)
-       // REFDIV = 1, OUTDIV = 1
-       #define CPU_PLL_CONFIG_VAL              0x40819400
+       #if CONFIG_40MHZ_XTAL_SUPPORT
+               // DIV_INT = 21 (40 MHz * 21/2 = 420 MHz), REFDIV = 1, RANGE = 0, OUTDIV = 1
+               #define CPU_PLL_CONFIG_VAL      MAKE_CPU_PLL_CONFIG_VAL(21, 1, 0, 1)
+       #else
+               #define FREQUENCY_NOT_SUPPORTED
+       #endif
 
-       // CLOCK_DIVIDER = 3 (SPI clock = 231,25 / 6 ~ 38,5 MHz)
+       // CLOCK_DIVIDER = 2 (SPI clock = 210 / 6 ~ 35 MHz)
        #define AR7240_SPI_CONTROL              0x42
 
-#elif (CFG_PLL_FREQ == CFG_PLL_475_475_237)
+       #define CFG_HZ_FALLBACK (420000000LU/2)
 
-       #define CFG_HZ  (475000000LU/2)
+#elif (CFG_PLL_FREQ == CFG_PLL_425_425_212)
 
        // CPU_DIV = 1, RAM_DIV = 1, AHB_DIV = 2
        #define CPU_CLK_CONTROL_VAL             MAKE_CPU_CLK_CONTROL_VAL(1, 1, 2)
 
-       // DIV_INT = 38 (25 MHz * 38/2 = 475 MHz)
-       // REFDIV = 1, OUTDIV = 1
-       #define CPU_PLL_CONFIG_VAL              0x40819800
+       #if CONFIG_40MHZ_XTAL_SUPPORT
+               #define FREQUENCY_NOT_SUPPORTED
+       #else
+               // DIV_INT = 34 (25 MHz * 34/2 = 425 MHz), REFDIV = 1, RANGE = 0, OUTDIV = 1
+               #define CPU_PLL_CONFIG_VAL      MAKE_CPU_PLL_CONFIG_VAL(34, 1, 0, 1)
+       #endif
 
-       // CLOCK_DIVIDER = 3 (SPI clock = 237,5 / 6 ~ 39,6 MHz)
+       // CLOCK_DIVIDER = 2 (SPI clock = 212 / 6 ~ 35 MHz)
        #define AR7240_SPI_CONTROL              0x42
 
-#elif (CFG_PLL_FREQ == CFG_PLL_487_487_243)
+       #define CFG_HZ_FALLBACK (425000000LU/2)
 
-       #define CFG_HZ  (487500000LU/2)
+#elif (CFG_PLL_FREQ == CFG_PLL_437_437_218)
 
        // CPU_DIV = 1, RAM_DIV = 1, AHB_DIV = 2
        #define CPU_CLK_CONTROL_VAL             MAKE_CPU_CLK_CONTROL_VAL(1, 1, 2)
 
-       // DIV_INT = 39 (25 MHz * 39/2 = 487,5 MHz)
-       // REFDIV = 1, OUTDIV = 1
-       #define CPU_PLL_CONFIG_VAL              0x40819C00
+       #if CONFIG_40MHZ_XTAL_SUPPORT
+               #define FREQUENCY_NOT_SUPPORTED
+       #else
+               // DIV_INT = 35 (25 MHz * 35/2 = 437 MHz), REFDIV = 1, RANGE = 0, OUTDIV = 1
+               #define CPU_PLL_CONFIG_VAL      MAKE_CPU_PLL_CONFIG_VAL(35, 1, 0, 1)
+       #endif
 
-       // CLOCK_DIVIDER = 3 (SPI clock = 243,75 / 8 ~ 30,5 MHz)
+       // CLOCK_DIVIDER = 3 (SPI clock = 218 / 8 ~ 27 MHz)
        #define AR7240_SPI_CONTROL              0x43
 
+       #define CFG_HZ_FALLBACK (437000000LU/2)
 
-#elif (CFG_PLL_FREQ == CFG_PLL_500_500_250)
+#elif (CFG_PLL_FREQ == CFG_PLL_440_440_220)
+
+       // CPU_DIV = 1, RAM_DIV = 1, AHB_DIV = 2
+       #define CPU_CLK_CONTROL_VAL             MAKE_CPU_CLK_CONTROL_VAL(1, 1, 2)
+
+       #if CONFIG_40MHZ_XTAL_SUPPORT
+               // DIV_INT = 22 (40 MHz * 22/2 = 440 MHz), REFDIV = 1, RANGE = 0, OUTDIV = 1
+               #define CPU_PLL_CONFIG_VAL      MAKE_CPU_PLL_CONFIG_VAL(22, 1, 0, 1)
+       #else
+               #define FREQUENCY_NOT_SUPPORTED
+       #endif
+
+       // CLOCK_DIVIDER = 3 (SPI clock = 220 / 8 ~ 27 MHz)
+       #define AR7240_SPI_CONTROL              0x43
+
+       #define CFG_HZ_FALLBACK (440000000LU/2)
 
-       #define CFG_HZ  (500000000LU/2)
+#elif (CFG_PLL_FREQ == CFG_PLL_450_450_225)
 
        // CPU_DIV = 1, RAM_DIV = 1, AHB_DIV = 2
        #define CPU_CLK_CONTROL_VAL             MAKE_CPU_CLK_CONTROL_VAL(1, 1, 2)
 
-       // DIV_INT = 40 (25 MHz * 40/2 = 500 MHz)
-       // REFDIV = 1, OUTDIV = 1
-       #define CPU_PLL_CONFIG_VAL              0x4081A000
+       #if CONFIG_40MHZ_XTAL_SUPPORT
+               #define FREQUENCY_NOT_SUPPORTED
+       #else
+               // DIV_INT = 36 (25 MHz * 36/2 = 450 MHz), REFDIV = 1, RANGE = 0, OUTDIV = 1
+               #define CPU_PLL_CONFIG_VAL      MAKE_CPU_PLL_CONFIG_VAL(36, 1, 0, 1)
+       #endif
 
-       // CLOCK_DIVIDER = 3 (SPI clock = 250 / 8 ~ 31,3 MHz)
+       // CLOCK_DIVIDER = 3 (SPI clock = 225 / 8 ~ 28 MHz)
        #define AR7240_SPI_CONTROL              0x43
 
-#elif (CFG_PLL_FREQ == CFG_PLL_500_250_250)
+       #define CFG_HZ_FALLBACK (450000000LU/2)
+
+#elif (CFG_PLL_FREQ == CFG_PLL_460_460_230)
+
+       // CPU_DIV = 1, RAM_DIV = 1, AHB_DIV = 2
+       #define CPU_CLK_CONTROL_VAL             MAKE_CPU_CLK_CONTROL_VAL(1, 1, 2)
+
+       #if CONFIG_40MHZ_XTAL_SUPPORT
+               // DIV_INT = 23 (40 MHz * 23/2 = 460 MHz), REFDIV = 1, RANGE = 0, OUTDIV = 1
+               #define CPU_PLL_CONFIG_VAL      MAKE_CPU_PLL_CONFIG_VAL(23, 1, 0, 1)
+       #else
+               // DIV_INT = 37 (25 MHz * 36/2 = 462 MHz), REFDIV = 1, RANGE = 0, OUTDIV = 1
+               #define CPU_PLL_CONFIG_VAL      MAKE_CPU_PLL_CONFIG_VAL(37, 1, 0, 1)
+       #endif
+
+       // CLOCK_DIVIDER = 3 (SPI clock = 230 / 8 ~ 29 MHz)
+       #define AR7240_SPI_CONTROL              0x43
+
+       #define CFG_HZ_FALLBACK (460000000LU/2)
+
+#elif (CFG_PLL_FREQ == CFG_PLL_475_475_237)
+
+       // CPU_DIV = 1, RAM_DIV = 1, AHB_DIV = 2
+       #define CPU_CLK_CONTROL_VAL             MAKE_CPU_CLK_CONTROL_VAL(1, 1, 2)
+
+       #if CONFIG_40MHZ_XTAL_SUPPORT
+               #define FREQUENCY_NOT_SUPPORTED
+       #else
+               // DIV_INT = 38 (25 MHz * 38/2 = 475 MHz), REFDIV = 1, RANGE = 0, OUTDIV = 1
+               #define CPU_PLL_CONFIG_VAL      MAKE_CPU_PLL_CONFIG_VAL(38, 1, 0, 1)
+       #endif
+
+       // CLOCK_DIVIDER = 3 (SPI clock = 237 / 8 ~ 30 MHz)
+       #define AR7240_SPI_CONTROL              0x43
+
+       #define CFG_HZ_FALLBACK (475000000LU/2)
+
+#elif (CFG_PLL_FREQ == CFG_PLL_480_480_240)
+
+       // CPU_DIV = 1, RAM_DIV = 1, AHB_DIV = 2
+       #define CPU_CLK_CONTROL_VAL             MAKE_CPU_CLK_CONTROL_VAL(1, 1, 2)
+
+       #if CONFIG_40MHZ_XTAL_SUPPORT
+               // DIV_INT = 24 (40 MHz * 24/2 = 480 MHz), REFDIV = 1, RANGE = 0, OUTDIV = 1
+               #define CPU_PLL_CONFIG_VAL      MAKE_CPU_PLL_CONFIG_VAL(24, 1, 0, 1)
+       #else
+               #define FREQUENCY_NOT_SUPPORTED
+       #endif
+
+       // CLOCK_DIVIDER = 3 (SPI clock = 240 / 8 ~ 30 MHz)
+       #define AR7240_SPI_CONTROL              0x43
+
+       #define CFG_HZ_FALLBACK (480000000LU/2)
+
+#elif (CFG_PLL_FREQ == CFG_PLL_487_487_243)
+
+       // CPU_DIV = 1, RAM_DIV = 1, AHB_DIV = 2
+       #define CPU_CLK_CONTROL_VAL             MAKE_CPU_CLK_CONTROL_VAL(1, 1, 2)
+
+       #if CONFIG_40MHZ_XTAL_SUPPORT
+               #define FREQUENCY_NOT_SUPPORTED
+       #else
+               // DIV_INT = 39 (25 MHz * 39/2 = 487 MHz), REFDIV = 1, RANGE = 0, OUTDIV = 1
+               #define CPU_PLL_CONFIG_VAL      MAKE_CPU_PLL_CONFIG_VAL(39, 1, 0, 1)
+       #endif
+
+       // CLOCK_DIVIDER = 3 (SPI clock = 243 / 8 ~ 30 MHz)
+       #define AR7240_SPI_CONTROL              0x43
+
+       #define CFG_HZ_FALLBACK (487000000LU/2)
+
+#elif (CFG_PLL_FREQ == CFG_PLL_500_500_250)
+
+       // CPU_DIV = 1, RAM_DIV = 1, AHB_DIV = 2
+       #define CPU_CLK_CONTROL_VAL             MAKE_CPU_CLK_CONTROL_VAL(1, 1, 2)
+
+       #if CONFIG_40MHZ_XTAL_SUPPORT
+               // DIV_INT = 25 (40 MHz * 25/2 = 500 MHz), REFDIV = 1, RANGE = 0, OUTDIV = 1
+               #define CPU_PLL_CONFIG_VAL      MAKE_CPU_PLL_CONFIG_VAL(25, 1, 0, 1)
+       #else
+               // DIV_INT = 40 (25 MHz * 40/2 = 500 MHz), REFDIV = 1, RANGE = 0, OUTDIV = 1
+               #define CPU_PLL_CONFIG_VAL      MAKE_CPU_PLL_CONFIG_VAL(40, 1, 0, 1)
+       #endif
+
+       // CLOCK_DIVIDER = 3 (SPI clock = 250 / 8 ~ 31 MHz)
+       #define AR7240_SPI_CONTROL              0x43
 
-       #define CFG_HZ  (500000000LU/2)
+       #define CFG_HZ_FALLBACK (500000000LU/2)
+
+#elif (CFG_PLL_FREQ == CFG_PLL_500_250_250)
 
        // CPU_DIV = 1, RAM_DIV = 2, AHB_DIV = 2
        #define CPU_CLK_CONTROL_VAL             MAKE_CPU_CLK_CONTROL_VAL(1, 2, 2)
 
-       // DIV_INT = 40 (25 MHz * 40/2 = 500 MHz)
-       // REFDIV = 1, OUTDIV = 1
-       #define CPU_PLL_CONFIG_VAL              0x4081A000
+       #if CONFIG_40MHZ_XTAL_SUPPORT
+               // DIV_INT = 25 (40 MHz * 25/2 = 500 MHz), REFDIV = 1, RANGE = 0, OUTDIV = 1
+               #define CPU_PLL_CONFIG_VAL      MAKE_CPU_PLL_CONFIG_VAL(25, 1, 0, 1)
+       #else
+               // DIV_INT = 40 (25 MHz * 40/2 = 500 MHz), REFDIV = 1, RANGE = 0, OUTDIV = 1
+               #define CPU_PLL_CONFIG_VAL      MAKE_CPU_PLL_CONFIG_VAL(40, 1, 0, 1)
+       #endif
 
-       // CLOCK_DIVIDER = 3 (SPI clock = 250 / 8 ~ 31,3 MHz)
+       // CLOCK_DIVIDER = 3 (SPI clock = 250 / 8 ~ 31 MHz)
        #define AR7240_SPI_CONTROL              0x43
 
-#elif (CFG_PLL_FREQ == CFG_PLL_562_281_140)
+       #define CFG_HZ_FALLBACK (500000000LU/2)
+
+#elif (CFG_PLL_FREQ == CFG_PLL_520_520_260)
 
-       #define CFG_HZ  (562500000LU/2)
+       // CPU_DIV = 1, RAM_DIV = 1, AHB_DIV = 2
+       #define CPU_CLK_CONTROL_VAL             MAKE_CPU_CLK_CONTROL_VAL(1, 1, 2)
+
+       #if CONFIG_40MHZ_XTAL_SUPPORT
+               // DIV_INT = 26 (40 MHz * 26/2 = 520 MHz), REFDIV = 1, RANGE = 0, OUTDIV = 1
+               #define CPU_PLL_CONFIG_VAL      MAKE_CPU_PLL_CONFIG_VAL(26, 1, 0, 1)
+       #else
+               #define FREQUENCY_NOT_SUPPORTED
+       #endif
+
+       // CLOCK_DIVIDER = 3 (SPI clock = 260 / 8 ~ 32 MHz)
+       #define AR7240_SPI_CONTROL              0x43
+
+       #define CFG_HZ_FALLBACK (520000000LU/2)
+
+#elif (CFG_PLL_FREQ == CFG_PLL_525_262_131)
 
        // CPU_DIV = 1, RAM_DIV = 2, AHB_DIV = 4
        #define CPU_CLK_CONTROL_VAL             MAKE_CPU_CLK_CONTROL_VAL(1, 2, 4)
 
-       // DIV_INT = 45 (25 MHz * 45/2 = 562,5 MHz)
-       // REFDIV = 1, OUTDIV = 1
-       #define CPU_PLL_CONFIG_VAL              0x4081B400
+       #if CONFIG_40MHZ_XTAL_SUPPORT
+               #define FREQUENCY_NOT_SUPPORTED
+       #else
+               // DIV_INT = 42 (25 MHz * 42/2 = 525 MHz), REFDIV = 1, RANGE = 0, OUTDIV = 1
+               #define CPU_PLL_CONFIG_VAL      MAKE_CPU_PLL_CONFIG_VAL(42, 1, 0, 1)
+       #endif
 
-       // CLOCK_DIVIDER = 1 (SPI clock = 140,625 / 4 ~ 35,2 MHz)
+       // CLOCK_DIVIDER = 1 (SPI clock = 131 / 4 ~ 33 MHz)
        #define AR7240_SPI_CONTROL              0x41
 
-#elif (CFG_PLL_FREQ == CFG_PLL_525_262_131)
+       #define CFG_HZ_FALLBACK (525000000LU/2)
 
-       #define CFG_HZ  (525000000LU/2)
+#elif (CFG_PLL_FREQ == CFG_PLL_560_280_140)
 
        // CPU_DIV = 1, RAM_DIV = 2, AHB_DIV = 4
        #define CPU_CLK_CONTROL_VAL             MAKE_CPU_CLK_CONTROL_VAL(1, 2, 4)
 
-       // DIV_INT = 42 (25 MHz * 42/2 = 525 MHz)
-       // REFDIV = 1, OUTDIV = 1
-       #define CPU_PLL_CONFIG_VAL              0x4081A800
+       #if CONFIG_40MHZ_XTAL_SUPPORT
+               // DIV_INT = 28 (40 MHz * 28/2 = 560 MHz), REFDIV = 1, RANGE = 0, OUTDIV = 1
+               #define CPU_PLL_CONFIG_VAL      MAKE_CPU_PLL_CONFIG_VAL(28, 1, 0, 1)
+       #else
+               // DIV_INT = 45 (25 MHz * 45/2 = 562 MHz), REFDIV = 1, RANGE = 0, OUTDIV = 1
+               #define CPU_PLL_CONFIG_VAL      MAKE_CPU_PLL_CONFIG_VAL(45, 1, 0, 1)
+       #endif
 
-       // CLOCK_DIVIDER = 1 (SPI clock = 131 / 4 ~ 32,8 MHz)
+       // CLOCK_DIVIDER = 1 (SPI clock = 140 / 4 ~ 35 MHz)
        #define AR7240_SPI_CONTROL              0x41
 
-#elif (CFG_PLL_FREQ == CFG_PLL_525_525_262)
+       #define CFG_HZ_FALLBACK (560000000LU/2)
 
-       #define CFG_HZ  (525000000LU/2)
+#elif (CFG_PLL_FREQ == CFG_PLL_580_290_145)
 
-       // CPU_DIV = 1, RAM_DIV = 1, AHB_DIV = 2
-       #define CPU_CLK_CONTROL_VAL             MAKE_CPU_CLK_CONTROL_VAL(1, 1, 2)
+       // CPU_DIV = 1, RAM_DIV = 2, AHB_DIV = 4
+       #define CPU_CLK_CONTROL_VAL             MAKE_CPU_CLK_CONTROL_VAL(1, 2, 4)
 
-       // DIV_INT = 42 (25 MHz * 42/2 = 525 MHz)
-       // REFDIV = 1, OUTDIV = 1
-       #define CPU_PLL_CONFIG_VAL              0x4081A800
+       #if CONFIG_40MHZ_XTAL_SUPPORT
+               // DIV_INT = 29 (40 MHz * 29/2 = 580 MHz), REFDIV = 1, RANGE = 0, OUTDIV = 1
+               #define CPU_PLL_CONFIG_VAL      MAKE_CPU_PLL_CONFIG_VAL(29, 1, 0, 1)
+       #else
+               #define FREQUENCY_NOT_SUPPORTED
+       #endif
 
-       // CLOCK_DIVIDER = 1 (SPI clock = 131 / 4 ~ 32,8 MHz)
+       // CLOCK_DIVIDER = 1 (SPI clock = 145 / 4 ~ 36 MHz)
        #define AR7240_SPI_CONTROL              0x41
 
+       #define CFG_HZ_FALLBACK (580000000LU/2)
+
+#elif (CFG_PLL_FREQ == CFG_PLL_600_300_200)
+
+       // CPU_DIV = 1, RAM_DIV = 2, AHB_DIV = 3
+       #define CPU_CLK_CONTROL_VAL             MAKE_CPU_CLK_CONTROL_VAL(1, 2, 3)
+
+       #if CONFIG_40MHZ_XTAL_SUPPORT
+               // DIV_INT = 30 (40 MHz * 30/2 = 600 MHz), REFDIV = 1, RANGE = 0, OUTDIV = 1
+               #define CPU_PLL_CONFIG_VAL      MAKE_CPU_PLL_CONFIG_VAL(30, 1, 0, 1)
+       #else
+               // DIV_INT = 48 (25 MHz * 48/2 = 600 MHz), REFDIV = 1, RANGE = 0, OUTDIV = 1
+               #define CPU_PLL_CONFIG_VAL      MAKE_CPU_PLL_CONFIG_VAL(48, 1, 0, 1)
+       #endif
+
+       // CLOCK_DIVIDER = 2 (SPI clock = 200 / 6 ~ 33 MHz)
+       #define AR7240_SPI_CONTROL              0x42
+
+       #define CFG_HZ_FALLBACK (600000000LU/2)
+
+#elif defined(CFG_PLL_FREQ)
+       #error Unknown frequency setting!
+#endif
+
+/*
+ * Check if clocks configuration is valid
+ */
+#ifdef FREQUENCY_NOT_SUPPORTED
+       #error Selected frequency setting is not supported with your reference clock!
 #endif
 
 /*
  * Available commands
  */
 #if defined(CONFIG_FOR_DLINK_DIR505_A1)
-       #define CONFIG_COMMANDS (CFG_CMD_MEMORY | CFG_CMD_FLASH | CFG_CMD_NET | CFG_CMD_PING | CFG_CMD_DATE | CFG_CMD_IMI )
+       #define CONFIG_COMMANDS (CFG_CMD_MEMORY | CFG_CMD_DHCP | CFG_CMD_PING | CFG_CMD_FLASH | CFG_CMD_NET | CFG_CMD_RUN | CFG_CMD_DATE | CFG_CMD_IMI | CFG_CMD_SNTP )
 #elif defined(CONFIG_FOR_8DEVICES_CARAMBOLA2)
-       #define CONFIG_COMMANDS (CFG_CMD_MEMORY | CFG_CMD_DHCP | CFG_CMD_PING | CFG_CMD_ENV | CFG_CMD_FLASH | CFG_CMD_NET | CFG_CMD_RUN | CFG_CMD_DATE | CFG_CMD_IMI | CFG_CMD_SNTP)
+       #define CONFIG_COMMANDS (CFG_CMD_MEMORY | CFG_CMD_DHCP | CFG_CMD_PING | CFG_CMD_ENV | CFG_CMD_FLASH | CFG_CMD_NET | CFG_CMD_RUN | CFG_CMD_DATE | CFG_CMD_IMI | CFG_CMD_SNTP)
 #else
-       #define CONFIG_COMMANDS (CFG_CMD_MEMORY | CFG_CMD_FLASH | CFG_CMD_NET | CFG_CMD_PING )
+       #define CONFIG_COMMANDS (CFG_CMD_MEMORY | CFG_CMD_DHCP | CFG_CMD_PING | CFG_CMD_FLASH | CFG_CMD_NET | CFG_CMD_RUN | CFG_CMD_DATE | CFG_CMD_SNTP )
 #endif
 
 // Enable NetConsole and custom NetConsole port
        #define OFFSET_PIN_NUMBER                               0x00FE00
 #endif
 
+/*
+ * PLL and clocks configurations from FLASH
+ *
+ * We need space for 4x 32-bit variables:
+ * - PLL_MAGIC_VARIABLE
+ * - values of registers:
+ *   - CPU_PLL_CONFIG (page 70 in datasheet)
+ *   - CLOCK_CONTROL  (page 71)
+ *   - SPI_CONTROL    (page 261)
+ */
+#if defined(CONFIG_FOR_DLINK_DIR505_A1)
+       /*
+        * We will store PLL and CLOCK registers
+        * configuration at the end of MAC data
+        * partition (3rd 64 KiB block)
+        */
+       #define PLL_IN_FLASH_MAGIC                              0x504C4C73
+       #define PLL_IN_FLASH_DATA_BLOCK_OFFSET  0x00020000
+       #define PLL_IN_FLASH_DATA_BLOCK_LENGTH  0x00010000
+       #define PLL_IN_FLASH_MAGIC_OFFSET               0x0000FFF0      // last 16 bytes
+#elif defined(CONFIG_FOR_8DEVICES_CARAMBOLA2)
+       /*
+        * We will store PLL and CLOCK registers
+        * configuration at the end of U-Boot
+        * image (4th 64 KiB block)
+        * It implies that binary image can't
+        * be bigger than 192 KiB!
+        *
+        * TODO: fix me
+        */
+       #define PLL_IN_FLASH_MAGIC                              0x504C4C73
+       #define PLL_IN_FLASH_DATA_BLOCK_OFFSET  0x00030000
+       #define PLL_IN_FLASH_DATA_BLOCK_LENGTH  0x00010000
+       #define PLL_IN_FLASH_MAGIC_OFFSET               0x0000FFF0      // last 16 bytes
+#else
+       /*
+        * All TP-Link routers have a lot of unused space
+        * in FLASH, in second 64 KiB block.
+        * We will store there PLL and CLOCK
+        * registers configuration.
+        */
+       #define PLL_IN_FLASH_MAGIC                              0x504C4C73
+       #define PLL_IN_FLASH_DATA_BLOCK_OFFSET  0x00010000
+       #define PLL_IN_FLASH_DATA_BLOCK_LENGTH  0x00010000
+       #define PLL_IN_FLASH_MAGIC_OFFSET               0x0000FFF0      // last 16 bytes
+#endif
+
 #include <cmd_confdefs.h>
 
 #endif /* __CONFIG_H */
index 3a644f0d3503b39e3eae2dabc8ce1c525e55b78c..edd3cf87107b127fb90e32d1649722b380eea90b 100755 (executable)
@@ -23,7 +23,7 @@
 #define CFG_ALT_MEMTEST
 #define        CFG_LONGHELP                                                                                    /* undef to save memory      */
 #define        CFG_PROMPT                      "uboot> "                                                       /* Monitor Command Prompt    */
-#define        CFG_CBSIZE                      512                                                                     /* Console I/O Buffer Size   */
+#define        CFG_CBSIZE                      1024                                                            /* Console I/O Buffer Size   */
 #define        CFG_PBSIZE                      (CFG_CBSIZE+sizeof(CFG_PROMPT)+16)      /* Print Buffer Size, was: def + 16 */
 #define        CFG_MAXARGS                     16                                                                      /* max number of command */
 #define CFG_MALLOC_LEN         512*1024                                                        // def: 128*1024
 /*
  ** PLL Config for different CPU/DDR/AHB frequencies
  */
-#define CFG_PLL_400_400_200                    1
-#define CFG_PLL_412_412_206                    2
-#define CFG_PLL_425_425_212                    3
-#define CFG_PLL_437_437_218                    4
-#define CFG_PLL_450_450_225                    5
-#define CFG_PLL_462_462_231                    6
-#define CFG_PLL_475_475_237                    7
-#define CFG_PLL_487_487_243                    8
-#define CFG_PLL_500_500_250                    9
-#define CFG_PLL_500_250_250                    10
-#define CFG_PLL_562_281_140                    11
-#define CFG_PLL_525_262_131                    12
-#define CFG_PLL_525_525_262                    13
+#define CFG_PLL_200_200_100            1
+#define CFG_PLL_200_200_200            2
+#define CFG_PLL_225_225_112            3
+#define CFG_PLL_225_225_225            4
+#define CFG_PLL_250_250_125            5
+#define CFG_PLL_250_250_250            6
+#define CFG_PLL_300_300_150            7
+#define CFG_PLL_325_325_162            8
+#define CFG_PLL_350_350_175            9
+#define CFG_PLL_360_360_180            10
+#define CFG_PLL_380_380_190            11
+#define CFG_PLL_400_400_200            12
+#define CFG_PLL_412_412_206            13
+#define CFG_PLL_420_420_210            14
+#define CFG_PLL_425_425_212            15
+#define CFG_PLL_437_437_218            16
+#define CFG_PLL_440_440_220            17
+#define CFG_PLL_450_450_225            18
+#define CFG_PLL_460_460_230            19
+#define CFG_PLL_475_475_237            20
+#define CFG_PLL_480_480_240            21
+#define CFG_PLL_487_487_243            22
+#define CFG_PLL_500_500_250            23
+#define CFG_PLL_500_250_250            24
+#define CFG_PLL_520_520_260            25
+#define CFG_PLL_525_262_131            26
+#define CFG_PLL_560_280_140            27
+#define CFG_PLL_580_290_145            28
+#define CFG_PLL_600_300_200            29
 
 // WASP
-#define CFG_PLL_566_400_200                    0x31
-#define CFG_PLL_566_500_250                    0x32
-#define CFG_PLL_600_1_2G_400_200       0x33
-#define CFG_PLL_560_480_240                    0x34
+#define CFG_PLL_566_400_200                    101
+#define CFG_PLL_566_500_250                    102
+#define CFG_PLL_600_1_2G_400_200       103
+#define CFG_PLL_560_480_240                    104
 
 /*-----------------------------------------------------------------------
  * Cache Configuration
index 9c8795c6f6835077fe672de64633abfaa1eb3bd0..ee1febb9b6f5cb08e7b92c5a3906cbc895469b95 100755 (executable)
 #undef CFG_HZ\r
 \r
 // CPU-RAM-AHB frequency setting\r
-#define CFG_PLL_FREQ           CFG_PLL_560_480_240\r
-#define CFG_HZ                 (560000000LU/2)\r
-#define AR7240_SPI_CONTROL     0x42\r
+#define CFG_PLL_FREQ                           CFG_PLL_560_480_240\r
+#define CFG_HZ_FALLBACK                                (560000000LU/2)\r
+#define        CFG_HZ                                          bd->bi_cfg_hz\r
+#define AR7240_SPI_CONTROL                     0x43\r
+#define AR7240_SPI_CONTROL_DEFAULT     AR7240_SPI_CONTROL\r
 /*\r
  * MIPS32 24K Processor Core Family Software User's Manual\r
  *\r
@@ -88,7 +90,7 @@
 /*\r
  * Available commands\r
  */\r
-#define CONFIG_COMMANDS (CFG_CMD_MEMORY | CFG_CMD_FLASH | CFG_CMD_NET)\r
+#define CONFIG_COMMANDS (CFG_CMD_MEMORY | CFG_CMD_DHCP | CFG_CMD_PING | CFG_CMD_FLASH | CFG_CMD_NET | CFG_CMD_RUN | CFG_CMD_DATE | CFG_CMD_SNTP )\r
 \r
 // Enable NetConsole and custom NetConsole port\r
 #define CONFIG_NETCONSOLE\r
index a00d9b8c372ea393ec71acc6f437b42092fbf51d..709d385cb6bd25904b663ba64c831aec6b3401d3 100755 (executable)
@@ -23,6 +23,8 @@
 
 #include <common.h>
 
+DECLARE_GLOBAL_DATA_PTR;
+
 static inline void mips_compare_set(u32 v){
        asm volatile ("mtc0 %0, $11" : : "r" (v));
 }
@@ -55,8 +57,18 @@ ulong get_timer(ulong base){
 void udelay(unsigned long usec){
        ulong tmo;
        ulong start = get_timer(0);
+       bd_t *bd = gd->bd;
+
+       /*
+        * We don't have filled the bd->bi_cfg_hz
+        * before relocation to RAM (bd is read only before that),
+        */
+       if((gd->flags & GD_FLG_RELOC) == 0){
+               tmo = usec * (CFG_HZ_FALLBACK / 1000000);
+       } else {
+               tmo = usec * (CFG_HZ / 1000000);
+       }
 
-       tmo = usec * (CFG_HZ / 1000000);
-       while ((ulong) ((mips_count_get() - start)) < tmo)
+       while ((ulong)((mips_count_get() - start)) < tmo)
                /*NOP*/;
 }
index 770e6dcb133fc40422ee025a59f032e444265006..eebff3c4a69f51e534ac326005764c0be8671a72 100755 (executable)
 
 #include <common.h>
 #include <command.h>
+#include <asm/mipsregs.h>
+#include <asm/addrspace.h>
 #include <malloc.h>
 #include <devices.h>
 #include <version.h>
 #include <net.h>
 #include <environment.h>
+#include "ar7240_soc.h"
+#include "../board/ar7240/common/ar7240_flash.h"
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -47,10 +51,7 @@ extern int timer_init(void);
 extern void all_led_on(void);
 extern void all_led_off(void);
 extern const char* print_mem_type(void);
-
-#if (BOARD == AP121)
 extern void ar7240_sys_frequency(u32 *cpu_freq, u32 *ddr_freq, u32 *ahb_freq);
-#endif
 
 ulong monitor_flash_len;
 
@@ -84,7 +85,7 @@ void *sbrk(ptrdiff_t increment){
 }
 
 static int display_banner(void){
-       printf("\n\n*****************************************\n*      %s      *\n*****************************************\n\n", version_string);
+       printf("\n\n*********************************************\n*        %s        *\n*********************************************\n\n", version_string);
        return(0);
 }
 
@@ -303,13 +304,20 @@ void board_init_r(gd_t *id, ulong dest_addr){
        int i;
        char *s;
        unsigned char buffer[6];
-#if (BOARD == AP121)
-       unsigned int ahb_freq, ddr_freq, cpu_freq;
-#endif
+       unsigned int ahb_freq, ddr_freq, cpu_freq, spi_freq;
 
        gd = id;
        gd->flags |= GD_FLG_RELOC; /* tell others: relocation done */
 
+       /* bd -> board data */
+       bd = gd->bd;
+
+       /* get CPU/RAM/AHB clocks */
+       ar7240_sys_frequency(&cpu_freq, &ddr_freq, &ahb_freq);
+
+       /* set bi_cfg_hz */
+       bd->bi_cfg_hz = (unsigned long)(cpu_freq >> 1);
+
 #ifdef BOARD_DEBUG
        printf("Now running in RAM - U-Boot at: %08lX\n", dest_addr);
 #endif
@@ -351,24 +359,23 @@ void board_init_r(gd_t *id, ulong dest_addr){
        /* configure available FLASH banks */
        size = flash_init();
 
-#if (BOARD == AP121)
-       /* display clocks */
-       ar7240_sys_frequency(&cpu_freq, &ddr_freq, &ahb_freq);
+       bd->bi_flashstart = CFG_FLASH_BASE;
+       bd->bi_flashsize = size;
+
+       // calculate SPI clock (we need to set bit 0 to 1 in SPI_FUNC_SELECT to access SPI registers)
+       ar7240_reg_wr(AR7240_SPI_FS, 0x01);
+       spi_freq = ahb_freq / (((ar7240_reg_rd(AR7240_SPI_CLOCK) & 0x3F) + 1) * 2);
+       ar7240_reg_wr(AR7240_SPI_FS, 0x0);
 
        // make MHz from Hz
        cpu_freq /= 1000000;
        ddr_freq /= 1000000;
        ahb_freq /= 1000000;
+       spi_freq /= 1000000;
 
-       printf("CLOCKS: %d/%d/%d MHz (CPU/RAM/AHB)\n", cpu_freq, ddr_freq, ahb_freq);
-#endif
-
+       printf("CLOCKS: %d/%d/%d/%d MHz (CPU/RAM/AHB/SPI)\n", cpu_freq, ddr_freq, ahb_freq, spi_freq);
        puts("\n");
 
-       bd = gd->bd;
-       bd->bi_flashstart = CFG_FLASH_BASE;
-       bd->bi_flashsize = size;
-
 #if CFG_MONITOR_BASE == CFG_FLASH_BASE
        bd->bi_flashoffset = monitor_flash_len; /* reserved area for U-Boot */
 #else
index 03ed468f913708605aa27bf65f1c06c8dcae00e1..709d385cb6bd25904b663ba64c831aec6b3401d3 100755 (executable)
@@ -23,6 +23,8 @@
 
 #include <common.h>
 
+DECLARE_GLOBAL_DATA_PTR;
+
 static inline void mips_compare_set(u32 v){
        asm volatile ("mtc0 %0, $11" : : "r" (v));
 }
@@ -35,7 +37,7 @@ static inline u32 mips_count_get(void){
        u32 count;
 
        asm volatile ("mfc0 %0, $9" : "=r" (count) :);
-       return count;
+       return(count);
 }
 
 /*
@@ -45,18 +47,28 @@ int timer_init(void){
        mips_compare_set(0);
        mips_count_set(0);
 
-       return 0;
+       return(0);
 }
 
 ulong get_timer(ulong base){
-       return mips_count_get() - base;
+       return(mips_count_get() - base);
 }
 
 void udelay(unsigned long usec){
        ulong tmo;
        ulong start = get_timer(0);
+       bd_t *bd = gd->bd;
+
+       /*
+        * We don't have filled the bd->bi_cfg_hz
+        * before relocation to RAM (bd is read only before that),
+        */
+       if((gd->flags & GD_FLG_RELOC) == 0){
+               tmo = usec * (CFG_HZ_FALLBACK / 1000000);
+       } else {
+               tmo = usec * (CFG_HZ / 1000000);
+       }
 
-       tmo = usec * (CFG_HZ / 1000000);
        while ((ulong)((mips_count_get() - start)) < tmo)
                /*NOP*/;
 }
index f2fce9ca51cc6a804106dae9ed12215a55cde8c9..7507f72a31d5cc719787af03adeaa4fe00387579 100755 (executable)
@@ -21,6 +21,9 @@
 #define BOOTP_VENDOR_MAGIC     0x63825363      /* RFC1048 Magic Cookie */
 
 #if (CONFIG_COMMANDS & CFG_CMD_NET)
+
+DECLARE_GLOBAL_DATA_PTR;
+
 #define TIMEOUT                                5               /* Seconds before trying BOOTP again */
 
 #ifndef CONFIG_NET_RETRY_COUNT
@@ -391,6 +394,8 @@ static void BootpHandler(uchar * pkt, unsigned dest, unsigned src, unsigned len)
  *     Timeout on BOOTP/DHCP request.
  */
 static void BootpTimeout(void){
+       bd_t *bd = gd->bd;
+
        if(BootpTry >= TIMEOUT_COUNT){
                puts("\n## Error: retry count exceeded, starting again!\n\n");
                NetStartAgain();
@@ -603,6 +608,7 @@ static int BootpExtended(u8 * e){
 #endif /* CFG_CMD_DHCP */
 
 void BootpRequest(void){
+       bd_t *bd = gd->bd;
        volatile uchar *pkt, *iphdr;
        Bootp_t *bp;
        int ext_len, pktlen, iplen;
@@ -899,6 +905,7 @@ static int DhcpMessageType(unsigned char *popt){
 }
 
 static void DhcpSendRequestPkt(Bootp_t *bp_offer){
+       bd_t *bd = gd->bd;
        volatile uchar *pkt, *iphdr;
        Bootp_t *bp;
        int pktlen, iplen, extlen;
@@ -958,6 +965,7 @@ static void DhcpSendRequestPkt(Bootp_t *bp_offer){
  *     Handle DHCP received packets.
  */
 static void DhcpHandler(uchar * pkt, unsigned dest, unsigned src, unsigned len){
+       bd_t *bd = gd->bd;
        Bootp_t *bp = (Bootp_t *)pkt;
        char tmp[22];
 
index b27f79ded0b5fd878e9700361b7b788d6e9ef5d9..3b023a43675279704d6e8d8bee4f0f3d802820b5 100755 (executable)
@@ -220,7 +220,7 @@ void ArpRequest(void){
 
        if((NetArpWaitPacketIP & NetOurSubnetMask) != (NetOurIP & NetOurSubnetMask)){
                if(NetOurGatewayIP == 0){
-                       puts("## Warning: gatewayip needed but not set\n");
+                       puts("** Warning: gatewayip needed but not set\n");
                        NetArpWaitReplyIP = NetArpWaitPacketIP;
                } else {
                        NetArpWaitReplyIP = NetOurGatewayIP;
@@ -235,6 +235,7 @@ void ArpRequest(void){
 
 void ArpTimeoutCheck(void){
        ulong t;
+       bd_t *bd = gd->bd;
 
        if(!NetArpWaitPacketIP){
                return;
@@ -542,6 +543,7 @@ static void startAgainHandler(uchar * pkt, unsigned dest, unsigned src, unsigned
 void NetStartAgain(void){
        char *nretry;
        int noretry = 0, once = 0;
+       bd_t *bd = gd->bd;
 
        if((nretry = getenv("netretry")) != NULL){
                noretry = (strcmp(nretry, "no") == 0);
@@ -730,6 +732,7 @@ static void PingHandler(uchar * pkt, unsigned dest, unsigned src, unsigned len){
 }
 
 static void PingStart(void){
+       bd_t *bd = gd->bd;
 #if defined(CONFIG_NET_MULTI)
        printf("Using %s device\n", eth_get_name());
 #endif /* CONFIG_NET_MULTI */
index 1ba60e803cca4920c0ea0102fab42b60df84064a..b440f01fdd945ea2d5aa74d3cd8d8d6c9b9dea48 100755 (executable)
@@ -31,6 +31,8 @@
 
 #if (CONFIG_COMMANDS & CFG_CMD_NET)
 
+DECLARE_GLOBAL_DATA_PTR;
+
 #define TIMEOUT                5               /* Seconds before trying BOOTP again */
 #ifndef        CONFIG_NET_RETRY_COUNT
 # define TIMEOUT_COUNT 5               /* # of timeouts before giving up  */
@@ -73,9 +75,9 @@ RarpHandler(uchar * dummi0, unsigned dummi1, unsigned dummi2, unsigned dummi3)
 /*
  *     Timeout on BOOTP request.
  */
-static void
-RarpTimeout(void)
-{
+static void RarpTimeout(void){
+       bd_t *bd = gd->bd;
+
        if (RarpTry >= TIMEOUT_COUNT) {
                puts ("\nRetry count exceeded; starting again\n");
                NetStartAgain ();
@@ -86,9 +88,8 @@ RarpTimeout(void)
 }
 
 
-void
-RarpRequest (void)
-{
+void RarpRequest (void){
+       bd_t *bd = gd->bd;
        int i;
        volatile uchar *pkt;
        ARP_t * rarp;
index e06c41188a4b099f2a401b62cf55dec8504f50b5..03e84323dba3a1eb52c7c87e4b61a8038c5da06c 100755 (executable)
@@ -12,6 +12,8 @@
 
 #if ((CONFIG_COMMANDS & CFG_CMD_NET) && (CONFIG_COMMANDS & CFG_CMD_SNTP))
 
+DECLARE_GLOBAL_DATA_PTR;
+
 //#define      DEBUG
 
 #define SNTP_TIMEOUT   10
@@ -80,6 +82,7 @@ static void SntpHandler(uchar *pkt, unsigned dest, unsigned src, unsigned len){
 }
 
 void SntpStart(void){
+       bd_t *bd = gd->bd;
 #ifdef DEBUG
        printf("%s\n", __FUNCTION__);
 #endif
index 36958002a850de44294847848359be13817bb651..3b30a207facc2125f5c36b61890c983a7c58a6b6 100755 (executable)
@@ -14,6 +14,8 @@
 
 #if (CONFIG_COMMANDS & CFG_CMD_NET)
 
+DECLARE_GLOBAL_DATA_PTR;
+
 #define WELL_KNOWN_PORT                69              /* Well known TFTP port # */
 #define TIMEOUT                                5               /* Seconds to timeout for a lost pkt */
 
@@ -177,6 +179,7 @@ static void TftpSend(void){
 }
 
 static void TftpHandler(uchar * pkt, unsigned dest, unsigned src, unsigned len){
+       bd_t *bd = gd->bd;
        ushort proto;
        ushort *s;
 
@@ -302,6 +305,8 @@ static void TftpHandler(uchar * pkt, unsigned dest, unsigned src, unsigned len){
 }
 
 static void TftpTimeout(void){
+       bd_t *bd = gd->bd;
+
        if(++TftpTimeoutCount > TIMEOUT_COUNT){
                puts("\n\n## Error: retry count exceeded, starting again!\n\n");
                NetStartAgain();
@@ -313,6 +318,8 @@ static void TftpTimeout(void){
 }
 
 void TftpStart(void){
+       bd_t *bd = gd->bd;
+
 #ifdef CONFIG_TFTP_PORT
        char *ep; /* Environment pointer */
 #endif